How to verify call on setter in kotlin using mockito? - mockito

interface LoginDisplay {
var username: String
var password: String
}
class LoginActivityLoginDisplay : LoginDisplay {
override var username: String
get() = usernameEditView.text.toString()
set(value) {
usernameEditView.setText(value)
}
override var password: String
get() = passwordEditView.text.toString()
set(value) {
passwordEditView.setText(value)
}
}
This is the example of code I'd like to test with Mockito as follows:
verify(contract.loginDisplay).username
Tricky thing is - that in this call i can only verify getter of field username, meanwhile I'd like to test call on setter of this field.
Any help?

It's simpler than you think. Calling:
verify(contract.loginDisplay).username = ""
will have the result you want. Setter setUsername on the mock of contract.loginDisplay will be called.

Related

Typescript object property incorrect type

I'm trying to write a simple Discord bot in TypeScript, using discord.js and clime.
I'm running into an issue where I'm trying to access an object property of a context object that I pass around, but it's always null. When I check the properties using either vscode's debugger or console.log, the object seems to have all of the properties that I would expect, except they're all nested one layer too deep.
export class DiscordCommandContext extends Context {
public message:Message;
public client:Client;
constructor (options:ContextOptions, message:Message, client:Client) {
super(options);
this.message = message;
this.client = client;
}
}
When I try accessing it the message property, it's always falsy (if block is skipped over).
if (context.message.guild) {
var settings = await repo.getRealmSettings(+context.message.guild.id);
if (key) {
embed.fields.push({name:key,value:settings[key]});
} else {
Object.keys(settings).forEach(property => {
embed.fields.push({name:property,value:settings[property]});
});
}
}
But in the console, I see this:
DiscordCommandContext appears to have nested "message" objects, one of the wrong type
I cannot access context.message.message, I get "Property 'message' does not exist on type 'Message'", which is as I would expect.
EDIT 1
My instantiation code looked like this:
var options:ContextOptions = {
commands: argArr,
cwd: ""
};
var context = new DiscordCommandContext(options, this.message, this.client );
Where argArr is a split string passed into the method and both this.message and this.client are populated in the constructor of the calling class (none are null)
I managed to get DiscordCommandContext to function properly by changing it to this:
export class DiscordCommandContext extends Context {
public message:Message;
public client:Client;
public realmSettings: RealmSettings;
constructor (options:ContextOptions, contextExtension:DiscordCommandContextValues) {
super(options);
this.message = contextExtension.message;
this.client = contextExtension.client;
this.realmSettings = contextExtension.realmSettings
}
}
export interface DiscordCommandContextValues {
message:Message;
client:Client;
realmSettings: RealmSettings;
}
And calling it like this:
var context = new DiscordCommandContext(options, {message:this.message, client:this.client, realmSettings: settings} );
I'm not sure if that's the right way or not... but it works.

MockMvc fails because of method invocation inside the controller method

I try to mock a controller which contains a util method inside even though I mock the util method, the mvcMock ignore the result from the when(...) and call the method again with empty parameters which lead to nullpointerexception
How I can ship the call of
when(utilMock.getOperatorsAdNameWrapper(userName, adNames)).thenReturn(roleSet);
with the mockMvc.perform?
#GetMapping(value = {"/wellbore"})
public String wellboreForm(Model model, #RequestParam("mode") String mode, HttpServletRequest request) {
Set<String> operators = new LinkedHashSet<>();
String userName = (String) request.getSession().getAttribute("userName");
Set<String> operatorsSet = (HashSet<String>) request.getSession().getAttribute("userRoles");
Set<String> operatorsAdName = util.getOperatorsAdNameWrapper(userName, operatorsSet);
operatorsAdName.forEach(adName -> {
Query query = new Query()
.setClassname(Wellbore.CLASS)
.eq(Wellbore.operatorsGroup, adName);
operators.addAll(getWellboresNameList(query));
});
model.addAttribute("wellboreDataList", operators);
model.addAttribute("wellboreData", new WellboreForm());
return "ui/selectWellbore";
}
public static Set<String> getOperatorsAdName(String userName, Set<String> operatorsAdName) {
operatorsAdName.removeIf(x -> x.equals(userName)
|| x.equals("SCOUT")
|| x.equals("GTO")
|| x.equals("KADME")
|| x.equals("offline_access")
|| x.equals("uma_authorization"));
return operatorsAdName;
}
public Set<String> getOperatorsAdNameWrapper(String userName, Set<String> operatorsAdName) {
return getOperatorsAdName(userName,operatorsAdName);
}
#Mock
private Util utilMock;
#Test
#DisplayName("GET /wellbore - Select Wellbore")
void testMockMvc() throws Exception {
HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
when(req.getAttribute("userName")).thenReturn("abcd");
String userName = (String) req.getAttribute("userName");
//Here I get the correct result Result
when(utilMock.getOperatorsAdNameWrapper(userName, adNames)).thenReturn(roleSet);
//another call made here with empy parameters to utilMock.getOperatorsAdNameWrapper("", null)
mockMvc.perform(get("/wellbore").param("mode","selectWellbore")
.sessionAttr("wellboreDataList", new LinkedHashSet<>())
.sessionAttr("wellboreData", new WellboreForm())
)
.andExpect(status().isOk())
.andExpect(view().name("ui/selectWellbore"))
.andExpect(model().attribute("wellboreDataList", hasSize(2)));
}
1) In the Controller move the line:
util.getOperatorsAdNameWrapper(userName, operatorsSet);
into a package level method:
Set<String> getOperatorsAdNameWrapper(userName, operatorsSet){
return util.getOperatorsAdNameWrapper(userName, operatorsSet);
}
2) In your test use SpyBean:
#SpyBean
private Controller controllerSpy;
#Test
#DisplayName("GET /wellbore - Select Wellbore")
void testMockMvc() throws Exception {
doReturn(roleSet).when(controllerSpy).getOperatorsAdNameWrapper(userName, adNames);
The general gist is that you cannot mock a static call with vanilla Mockito. You have to refactor a bit first.
The Problem was with the Util class
since I am using mockmvc as unit testing, not as integration test by standaloneSetup
mockMvc = MockMvcBuilders
//To avoid loading springContext
.standaloneSetup(controller)
.setViewResolvers(viewResolver())
.build();
so the Util class not loaded to the context to solve this you have to option
Move the wrapper method in the util class to the service class and from there you can wrapper the static method in the Util class
Add the util class to the controller constructor

Typescript Class in NodeJS

I am trying to create and use some Data Classes in NodeJs which i defined in Typescript and are at a point where i am wondering if there is a simpler way.
In javascript i was able to do
let myBuilding = new Building
Then i was able to just do
myBuilding.col1 = "Wall"
myBuilding.col2 = "None"
and so on
in typescript it doesn't like it if i don't declare everything at the point of declaration. Is there a way to initialize a class with blank values and then assign them later ? Also what happens when there is something that doesnt get a value assigned ? in javascript we dont get that item returned which is great when parsing from json to a class
Here is what a class of mine looks like
export class Exterior {
public exterior: string;
public fencing: string;
public security: string;
public sewer: string;
public lot: string;
public pool: string;
public patioPorch: string;
public spa: string;
constructor(exterior: string, fencing: string, security: string, sewer: string, lot: string, pool: string,
patioPorch: string, spa: string) {
this.exterior = exterior;
this.fencing = fencing;
this.security = security;
this.sewer = sewer;
this.lot = lot;
this.pool = pool;
this.patioPorch = patioPorch;
this.spa = spa;
}
}
when you declare a type you can just make things optional:
class Building {
height?: number;
}
now typescript won't complain if you don't declare a height right away but you still can't add extra undeclared fields like width.
You can also declare things as a Partial<Building> if they meet some subset of the interface but not all of the required fields.
Here are four ways of achieving this:
class Foo {
// This will not do anything, so remove it
constructor() {}
// this will be undefined initially
private internalA!: number;
public get fieldA() {
return this.internalA
}
public set fieldA(internalAValue: number) {
this.internalA = internalAValue;
}
// this will be undefined initially
public fieldB!: boolean;
// this will be undefined initially
public fieldC!: string;
// this will be "example-initial-value" initially
public fieldD: string = "example-initial-value";
}
const foo = new Foo();
// Method 1 using setters
foo.fieldA = 2;
alert(foo.fieldA);
// Method 2 using simple assigning
foo.fieldB = true;
alert(foo.fieldB);
// Method 3 using Object.defineProperty
Object.defineProperty(foo, 'fieldC', {
value: "test",
writable: false
});
alert(foo.fieldC);
// Method 4 using Object.assign
Object.assign(foo, {fieldD: "hello"});
alert(foo.fieldD);
Be very careful or even avoid Object.defineProperty and Object.assign directly without creating a wrapper that enforces the types. They both have many ways of getting around / forgetting your type system.
setter method and direct public field assignment are the easiest type safe ways.
You can run it here
Here is a way for setting multiple things in one go without initialising first
interface IFooParams {
fieldA: number;
fieldB: boolean;
fieldC: string;
fieldD: string
}
class Foo {
// this will be undefined initially
public fieldA!: number;
// this will be undefined initially
public fieldB!: boolean;
// this will be undefined initially
public fieldC!: string;
// this will be "example-initial-value" initially
public fieldD: string = "example-initial-value";
public setAllInOneGo(params: IFooParams): void {
this.fieldA = params.fieldA;
this.fieldB = params.fieldB;
this.fieldC = params.fieldC;
this.fieldD = params.fieldD;
}
}
const foo = new Foo();
// Whenever:
foo.setAllInOneGo({
fieldA: 2,
fieldB: false,
fieldC: "hello",
fieldD: "world"
});

Can I overload method in module.export in node.js?

I have an app.js with this code:
var addnote = (title,body) => { /* enter code here */ }
module.exports = {addnote};
Can I add another addnotes function with different parameters to that file?
Function overloading in JavaScript does not exist like in other programming languages such as C# and Java.
What you should be looking to do is pass an object as a parameter that has properties attached and filter them out there..
You could call different functions from your little 'mapping function' just implement the logic there if it isn't big (to keep the code clear).
function foo(parameters){
var title = parameters.title;
var body = parameters.body;
if(parameters.extraProperty){
// oh we have extraProperty passed in too, run a different function?
bar(title, body, parameters.extraProperty); // ??
}
}
foo({title: 'Title', body: 'Body', extraProperty: 'This is extra...'});
If this is your own custom module, you can use the concept of function overriding, where each child class can have its own way to handle something and also have a default way to do things.
class Parent {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello ${this.name}`);
}
}
class Child1 extends Parent {
constructor(name) {
super(name);
}
greet() {
console.log(`Hey there ${this.name}. This is Child 1`);
}
}
class Child2 extends Parent {
constructor(name) {
super(name);
}
greet() {
console.log(`Hi there ${this.name}. This is Child 2`);
}
}
const o1 = new Child1('Foo')
const o2 = new Child2('Foo')
o1.greet();
o2.greet();
But if you are trying to override a function in an external module(You do not have access to that code, like a library), my suggestion is to create a wrapper and add functionality there.

How to override functions from String class in C#

For example, I need to see if a string contains a substring, so I just do:
String helloworld = "Hello World";
if(helloworld.Contains("ello"){
//do something
}
but if I have an array of items
String helloworld = "Hello World";
String items = { "He", "el", "lo" };
I needed to create a function inside the String class that would return true if either of
the items inside the array is contained in the string, for example.
I would like to override the function Contains(string) with Contains(IEnumerable) for this scenario, instead of creating a function in another class. Is it possible to do this, and if so, how can we override the function? Thank you very much.
So here goes the complete solution (thanks guys):
public static bool ContainsAny(this string thisString, params string[] str) {
return str.Any(a => thisString.Contains(a));
}
You can't override the function, but you can make an extension method for this:
public static class StringExtensions {
public static bool ContainsAny(this string theString, IEnumerable<string> items)
{
// Add your logic
}
}
You'd then call this just like a normal method on a string, provided you reference the assembly and include the namespace:
String helloworld = "Hello World";
String[] items = new string[] { "He", "el", "lo" };
if (helloworld.ContainsAny(items)) {
// Do something
}
(Granted, you could call this "Contains", like the standard string method, but I would prefer to give it a more explicit name so it's obvious what you're checking...)
Why not keep things simple and use the Any extension method?
string helloworld = "Hello World";
string[] items = { "He", "el", "lo" };
if (items.Any(item => helloworld.Contains(item)))
{
// do something
}

Resources