Im trying to verify that my method doRequestImpl() has been called 3 times in my test - It has the signature: suspend fun <T> doRequestImpl(handler: suspend () -> T): T
In my test i have:
coVerify(exactly = 3) {
sut.doRequestImpl(any())
}
sut is a spy of a real class implementation.
But something is not right, as with a debugger i can see that the coVerify() actually does a call to sut.doRequestImpl() using a kotlin.jvm.functions.Function1-type as argument which throws an exception and making the test to fail.
What am i doing wrong? Im guessing my argument matcher is not the right one but....?
Related
I have the following function
public Mono<Integer> revertChange() { someService.someMethod() .retryWhen(3 times, with 150millis of delay, if specific error occured) .onError(e -> log_the_error); }
And I have a simple unit test that summpose to verify that the someService.someMethod was called exactly 3 times
`class Test {
#InjectMocks
SomeService someService;
#Test
void shouldCallSomeServiceExactlythreetimes_whenErrorOccured() {
verify(someService).someMethod(3)//someMethod invoked 3 times
}
}
`
The problem is that the verify block does not catches that the someMethod was executed 3 times, it says only 1. I am using junit 5 and jmockit, maybe there are better alternatives specific for reactive mocks, any ideas guys?
Verification block does not catch multiple execution of the method
Mockito.verify(someService, Mockito.times(3)).someMethod();
from https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html :
Arguments passed are compared using equals() method. Read about ArgumentCaptor or ArgumentMatcher to find out other ways of matching / asserting arguments passed.
Although it is possible to verify a stubbed invocation, usually it's just redundant. Let's say you've stubbed foo.bar(). If your code cares what foo.bar() returns then something else breaks(often before even verify() gets executed). If your code doesn't care what foo.bar() returns then it should not be stubbed.
check also https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#4
for verification with time out check https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#verification_timeout
this snippet passes as soon as someMethod() has been called 2 times under 150 ms
Mockito.verify(someService, Mockito.timeout(150).times(2)).someMethod();
After careful investigation of the problem and deep dive to project reactor internals, the solution looks pretty simple the method that I am calling needs to be wrapped with Mono.deffer(() -> someService.someMethod()) that will eagerly every time when you call it
Im trying to create mock method to run Unit test for function below:
class SomeClass{
fun <T> someMethod(str: String, action: (String) -> T): T {
// do something
return action(str);
}
}
My mock method:
val mock = Mockito.mock(SomeClass::class.java)
`when`(mock.someMethod<Unit>(anyString(), any())).then { invocation ->
#Suppress("UNCHECKED_CAST")
(invocation.arguments[1] as (String) -> Unit).invoke("Some String...")
}
but I meet the following issue, when running it failed and throw exception: java.lang.IllegalStateException at line "when(mock.someMethod(anyString(), any())).then { invocation ->"
do you have any idea to fix it?
Thank for your help
First of all: Using Mockito directly from Kotlin is annoying, e.g. because when is a keyword in the language and you have to escape it using backticks. There is a wrapper library which fixes most of the issues: https://github.com/nhaarman/mockito-kotlin. Otherwise, mockk is a good alternative mocking framework as well.
Regarding your problem:
It is probably related to the fact that Mockito and Kotlin don't work too well together; it works for me using the library mentioned above. Can you share more information about the error message?
can someone help me to figure out how i can unit tests the below code effectively. its kotlin but can be anything:
myMainObject.doSomethingSpecial({ differentObject ->
differentObject.doFirst()
differentObject.doSecond()
differentObject.doThird()
})
i would like to test that doSomethingSpecial actually works.
i thought about trying to mock the lambda:
val function1: () -> Int = mock()
whenever(function1.invoke())
.thenReturn(1)
but this is not what i really want. i want to test that all the methods in the lamda get called so i want to test that doFirst,doSecond,doThird, etc are all called i think is how best to unit test this. do i have use argument capture for this, how ? To be clear, my question is how to unit test the method doSomethingSpecial ?
You can try to split the problem into two simpler problems:
you can test the doSomethingSpecial (which I suppose calls the function it receives a parameter) passing a fake function as parameter and testing it was called
you can test the lambda giving it a name and testing it as function: you call it passing a mock for differentObject and test mock's method were called
So, in pseudo-code:
val myFunction = { differentObject ->
differentObject.doFirst()
differentObject.doSecond()
differentObject.doThird()
differentObject.doFourth()
differentObject.doFifth()
}
myMainObject.doSomethingSpecial(myFunction)
// Invoke doSomethingSpecial with fake parameter
val fakeFunction = ...
myMainObject.doSomethingSpecial(fakeFunction)
// Assert fakeFunction was called
// Invoke myFunction with mock parameter
val mockObject = ...
myFunction(mockObject)
// Assert mockObject.doNth was called
I hope this approach can help you toward a real solution!
I have a method that is shown as below and this in turn call multiple private methods, that I won't be posting here.
#Bean
public CommandLineRunner registerStartersAndReaders(final Vertx vertx, final SpringVerticleFactory springVerticleFactory,
final SpringUtil springUtil, final GslConfig gslConfig) {
return args -> {
// Scan all the beans annotated with the #ElasticsearchBatchDataListener annotation.
List<Pair<Object, Method>> listenerMethods = springUtil.getListenerMethods();
// Deploy the starters per listener.
deployVerticle(listenerMethods, jsonConfig -> deployStarterVerticle(vertx, springVerticleFactory, jsonConfig), config);
// Deploy the reader verticles.
deployVerticle(listenerMethods, jsonConfig -> deployReaderVerticle(vertx, springVerticleFactory, jsonConfig), config);
setupTriggers(vertx, listenerMethods, config);
};
}
Then I have a test method for it :
#Test
public void registerStartersAndReadersTest() {
when(springUtil.getListenerMethods()).thenReturn(value);
CommandLineRunner runner = config.registerStartersAndReaders(vertx, springVerticleFactory, springUtil, config);
assertNotNull(runner);
}
Here, all the parameters passed into the method call are mocks. The problem is, when I run this test, it passes but it returns the value without getting into the private methods as it just returns 'args'.
Can someone please guide me, as to how I can make my test cover all the possible code. I am not supposed to change my code for the test.
I think you got confused with the lamba expression, and believe me it is very confusing in the beginning. But once you are fluent with it, it will be a breeze.
So here you got the instance of CommandLineRunner from method registerStartersAndReaders call, and your assertNotNull PASS as you have the not null instance, but until you call the run method of FunctionalInterface nothing will be executed.
Add runner.run(args) to execute the method(s) in your test case.
How do I check if Create was not called without using the Rhino Mocks AssertWasNotCalled method.
Here is the test:
[Test]
public void When_try_to_create_directory_that_already_exits_return_false()
{
var directoryInfoMock = MockRepository.GenerateMock<IDirectoryInfoWrap>();
directoryInfoMock.Stub(x => x.Exists).Return(true);
directoryInfoMock.Expect(x => x.Create());
Assert.AreEqual(false, new DirectoryInfoSample().TryToCreateDirectory(directoryInfoMock));
directoryInfoMock.VerifyAllExpectations();
}
Also, can someone clarify what Stub does.
directoryInfoMock.Stub(x => x.Exists).Return(true);
ensures that any call to the property directoryInfoMock.Exists will return true. But if the property is never call or called many times, it will not cause the test to fail. The purpose of the stub is to provide some meal to your code under test so that it can run normally.
directoryInfoMock.Expect(x => x.Create());
expects that the method directoryInfoMock.Create be called at least once. If not, an exception will be thrown by Rhino.Mocks during the execution of directoryInfoMock.VerifyAllExpectations().
So basically, your unit test should work as expected. What is the output of the test?
UPDATE:
You might want to specify an explicit number of times the method should be called as well. This can be done by using Repeat.x with x is Once(), Twice(), Never(), or Times(N).
directoryInfoMock.Expect(x => x.Create()).Repeat.Never();
This expects that Create is never called. And of course your test will fail if it is actually called.
If you need to make sure that only the methods you expect are called you can consider using strict mocks. Then you will get an exception when a method was called that was not expected on your mock, the only change to your code is when you create your mock:
var directoryInfoMock = MockRepository.GenerateStrictMock<IDirectoryInfoWrap>();
if you know exactly which method shouldn't be called its better to use AssertWasNotCalled (you use it after your test was executed). This way you don't tie your test with your code so closely.