What is the analogue of Mockito.verifyZeroInteractions(obj) in the Mockk library? - kotlin

I want to switch to Mockk, but i cant find analogue of this method in Mockk
It doesn't work
verify (exactly = 0) { obj }

The way you are trying it, is missing the method or variable
verify (exactly = 0) { obj.something }
Using the exactly zero approach would require
confirmVerified(obj)
To be sure nothing else was called.
The exact equivalent would be:
verify { obj wasNot Called }

Related

Mockk matching and overloaded function withArg

Hello I am trying to find a way to match an overloaded function inside of the verify using withArg
The doc doesnt really point this out
every { getResponse.Ids } returns listOf(121212L)
assert( client.getExtIds(Ids) )
verify {
client.getExtIdsCall().call(
withArg {
assertEquals(GetExtIdsRequest.builder()
.withIds("foo")
.withType("bar")
.build().hashCode(), it.hashCode()
)
}
)
}
Something like above. But unfortunately I cant because the client.getExtIdsCall().call() accepts two different types of objects. One of which has the hashCode I want. So the it can not be referred correctly to call the hashCode function
You can resolve this by explicitly specifying the type parameter of function withArg, e.g. if you want your parameter to be a Long, you can write:
withArg<Long> { ... }

Kotlin ConflatedBroadcastChannel.offer() doesn't work?

I am sending a value via MyRepository.myConflatedChannel.offer(myvalue).
I then expect to receive it in collect { } or onEach { } blocks in my ViewModel. However, neither function is invoked. It is as if nothing is passed down the ConflatedBroadcastChannel.
Has anybody seen a similar problem?
Make sure you properly work with receiving values.
If you use the ConflatedBroadcastChannel, you can use either OpenSubscription to get a ReceiveChannel or you can represent it as flow (with asFlow).
Note that consume and consumeEach are terminal, they perform an action and then cancel the channel after the execution of the block. See this.
First case:
val receivingChannel = MyRepository.myConflatedChannel.openSubscription()
// then you can consume values using for example a for loop, e.g.:
launch {
for (value in receivingChannel) {
// do something
}
}
Second case:
val receivingFlow = MyRepository.myConflatedChannel.asFlow()
launch {
receivingFlow.collect {
// do something
}
}

Can you verify a property setter using mockk?

We had a few tests in Java and Mockito, which we are progressively converting into Kotlin and Mockk. There's a problem, though. This simple line:
verify(mockedInteractor).setIndex(1);
When we move it to mockk, we get this:
verify { mockedInteractor.index = 1 }
This of course passes the tests, as it's not actually checking that index was set to 1. It's simply setting the mock's variable to 1. This below has the same effect.
verify { mockedInteractor.setIndex(1) }
Is there a way to verify setters?
You could try capture:
val fooSlot = slot<String>()
val mockBar = mockk<Bar>()
every { mockBar.foo = capture(fooSlot) } answers { }
assertEquals(fooSlot.captured, "expected")
Yes you can:
verify { mockedInteractor setProperty "index" value 1 }
There are more examples in here https://mockk.io/#private-functions-mocking--dynamic-calls
Compact solution without hardcoded string:
verify { mockedInteractor setProperty MockedInteractor::index.name value 1 }
where MockedInteractor is mockedInteractor class
I'm wondering if this was asked about an earlier version of Mockk, afterall, it is and old question.
verify { mockedInteractor.index = 1 }
does exactly what it says - it verifies that mockedInteractor.index was set to 1.
If you don't believe me, try it. Try setting mockedInteractor.index to something other than 1 in the product code and watch this test fail.
Maybe this was a Mockk bug that has since been fixed.
You can now relax this requirement for unit functions when defining your mock.
val foo = mockk<Foo>(relaxUnitFun = true)
Enabling this setting on your mock means you will not need to use justRun or any variation of that code (as per the Mockk documentation) when verifying unit functions are invoked.

Equivalent of times() in JMockIt?

I dont think minInvocation or maxInvocation is equivalent to times() in Mockito. Is there?
Please see this questions: Major difference between: Mockito and JMockIt
which has not been answered yet by anyone.
Edit
I found the answer myself: Adding it here for others who need this answered:
The solution is to use DynamicPartialMocking and pass the object to the constructor of the Expectations or NonStrictExpectations and not call any function on that object.
Then in the Verifications section, call any function on the object for which you want to measure the number of invocations and set times = the value you want
new NonStrictExpectations(Foo.class, Bar.class, zooObj)
{
{
// don't call zooObj.method1() here
// Otherwise it will get stubbed out
}
};
new Verifications()
{
{
zooObj.method1(); times = N;
}
};
I found the answer myself: Adding it here for others who need this answered:
The solution is to use DynamicPartialMocking and pass the object to the constructor of the Expectations or NonStrictExpectations and not call any function on that object.
Then in the Verifications section, call any function on the object for which you want to measure the number of invocations and set times = the value you want
new NonStrictExpectations(Foo.class, Bar.class, zooObj)
{
{
// don't call zooObj.method1() here
// Otherwise it will get stubbed out
}
};
new Verifications()
{
{
zooObj.method1(); times = N;
}
};

How to register component interface in wxwebconnect?

I'm doing an experiment with wxWebConnect test application, incorporating the xpcom tutorial at "http://nerdlife.net/building-a-c-xpcom-component-in-windows/"
I adapt MyComponent class as necessary to compile together with testapp.exe (not as separate dll), and on MyApp::OnInit I have the following lines:
ns_smartptr<nsIComponentRegistrar> comp_reg;
res = NS_GetComponentRegistrar(&comp_reg.p);
if (NS_FAILED(res))
return false;
ns_smartptr<nsIFactory> prompt_factory;
CreateMyComponentFactory(&prompt_factory.p);
nsCID prompt_cid = MYCOMPONENT_CID;
res = comp_reg->RegisterFactory(prompt_cid,
"MyComponent",
"#mozilla.org/mycomp;1",
prompt_factory);
Those lines are copied from GeckoEngine::Init(), using the same mechanism to register PromptService, etc. The code compiles well and testapp.exe is running as expected.
I put javascript test as below :
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const cid = "#mozilla.org/mycomp;1";
obj = Components.classes[cid].createInstance();
alert(typeof obj);
// bind the instance we just created to our interface
alert(Components.interfaces.nsIMyComponent);
obj = obj.QueryInterface(Components.interfaces.nsIMyComponent);
} catch (err) {
alert(err);
return;
}
and get the following exception:
Could not convert JavaScript argument arg 0 [nsISupport.QueryInterface]
The first alert says "object", so the line
Components.classes[cid].createInstance()
is returning the created instance.
The second alert says "undefined", so the interface nsIMyComponent is not recognized by XULRunner.
How to dynamically registering nsIMyComponent interface in wxWebConnect environment ?
Thx
I'm not sure what is happening here. The first thing I would check is that your component is scriptable (I assume it is, since the demo you copy from is). The next thing I would check is whether you can instantiate other, standard XULRunner components and get their interface (try something like "alert('Components.interfaces.nsIFile');" - at least in my version of wxWebConnect this shows an alert box with string "nsIFile".
Also, I think it would be worth checking the Error Console to make sure there are no errors or warnings reported. A magic string to do that (in Javascript) is:
window.open('chrome://global/content/console.xul', '', 'chrome,dialog=no,toolbar,resizable');