EasyMock JUnit testing throws error on the setter method - java

I am using easyMock for JUnit testing. I want to test a method which gets a Project object as its arguments and sets the modify date of that project and persists it in db.
So e.g.
public void setProject(Project project) {
project.setModifyDate(new Date());
this.reporsitory.persist(project);
}
Now at my test method I have tow mocked projects. For one of them I have set the return value of the getModifyDate. For the other mocked project object I just call the setProject(mockedProject); Now I assertEqual these two project objects.
The problem is easymock throws me an error at the project.setModifyDate(new Date()) of the class which I am testing.
Exception : Unexpected method call project.setModifyDate(..).. Expected:1, Actual:0.
It seems that it does not expect the setter method. Could you please let me know what I am doing wrong.
Thanks.

Yes, it is because of the type of mock object you created. It expects your code to call every method you defined when the one call executes. I cannot remember the exact name but i think it is something like nicemock, versus a strictmock whick makes your code execute every expected method. You should use EasyMock.createNiceMock() for your mock object. The error you have is because it expects you to call setModifyDate but your code didn't for that call.
Your call is unexpected because you must have not put EasyMock.expected for that method. You need to add your mock object .expected(getMethod).andReturns(something).

Related

Do I always need `when/thenReturn` for mock object's functions

I am writing a test in Scala where I do something like this --
val svc = mock[Service]
Initializer.fun1(svc)
fun1 internally calls a function svc.fun2 which returns Unit.
My test is failing when it tries to execute svc.fun2 with this error -
java.lang.NoSuchMethodError: org.mockito.internal.invocation.ArgumentsProcessor.expandArgs
As svc has already been mocked, I shouldn't have to mock fun2 ,right ?
Unless I want fun2 to return a specific value
Same thing worked for another codebase of mine, but that's using a different library for Mockito
Update :
I also tried adding a when/thenReturn for fun2 but still getting the same error.
I just did this
when(svc.fun2()) thenReturn()
since it's supposed to return UNIT

EasyMock missing behavior even though it's defined

No matter what I do, I get the following error when trying to mock a method
java.lang.IllegalStateException: missing behavior definition for the preceding method call:
ConfigurationSection.get("country-language")
Usage is: expect(a.foo()).andXXX()
My code for testing:
EasyMock.expect(section.getString("country-language")).andReturn("US");
LocaleManager.updateLocale(section, Collections.emptyList());
EasyMock.expectLastCall();
replayAll();
Assert.assertEquals("Test", TranslatedMessage.translate("test"));
verifyAll();
The expect andReturn is called for the mocked class, and the static upateLocale method calls the method, first thing.
The strange thing is this test works fine:
EasyMock.expect(section.getString("country-language")).andReturn("US");
replayAll();
Assert.assertEquals("US", section.getString("country-language"));
verifyAll();
But calling it from an external method doesn't work.
Your mock says:
EasyMock.expect(section.getString("country-language"))
The error says:
ConfigurationSection.get("country-language")
You are not mocking get("country-language"). You are mocking getString("country-language").
Unrelated, but verify is a maintenance nightmare and should generally be avoided. This ties test code directly to an implementation. Tests should focus on inputs and outputs if at all possible.

Issue with PowerMockito verifyStatic() method for a static recursive function in Java

I am new to Mockito and PowerMockito. I have a test method where I use PowerMockito to mock a static recursive method. I need to verify that particular method is invoked 2 times, but the test case fails. Also the actual method is not hit.
This is the code.
Testing method:
public class Util {
public static void methodToTest(String a, String b) {
..............
methodToTest(c, d);
}
}
Test case :
public void testMethodToTest() {
PowerMockito.mockStatic(Util.class);
Util.methodToTest(e, f);
verifyStatic(Util.class, Mockito.times(2));
Util.methodToTest(Matchers.anyString(), Matchers.anyString());
}
But when I run the test it fails with the following error.
Wanted 2 times but was 1 time.
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:182)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:164)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:141)
Ideally with Util.methodToTest(e, f) call,it should call the actual methodToTest twice.
I debugged the code and then I noticed that Util.methodToTest(e, f) call does not go inside the actual method.
What is the issue in this code? How can I verify that this recursive method is getting called twice?
Powermock version - 1.7.4
The problem here is that you are invoking intercepted method from inside of spied/mocked object. Interception is made when call is made from the outside. So original call is "registered" but not the internal one.
I am not sure it is a bug or expected behavior, but I have ran into the same issue some time ago (but not with statics) and If I recall I redesigned the test.

Mock a Method with complex type

While mocking a method, which have complex type, returning null in java
public void sendRequest(OnlineRequest request) {
OnlineResponse response = client.handleRequest(request);
System.out.println( response);
}
Mockito.when(client.handleRequest(request)).thenReturn(new OnlineResponse());
If I understand correctly, your issue is that System.out.println(response); prints null?
This is most likely due to the fact that client.handleRequest() is not being called with the request you expect. This may be an error somewhere in code you haven't provided us, OR it may simply be due to the fact that OnlineRequest does not have an implementation of equals/hash-code, so when() is never triggered because it is not called with the exact same instance of OnlineRequest as you use in your unit tests.
You might wish to test that handleRequest is called with exactly the object you expect. This can be accomplished using verify():
verify(client).handleRequest(request);
in your unit test. This too is dependent on the equals/hash-code implementation to determine whether request is the expected parameter or not.

Mocking a Spy method with Mockito

I am writing a unit test for a FizzConfigurator class that looks like:
public class FizzConfigurator {
public void doFoo(String msg) {
doWidget(msg, Config.ALWAYS);
}
public void doBar(String msg) {
doWidget(msg, Config.NEVER);
}
public void doBuzz(String msg) {
doWidget(msg, Config.SOMETIMES);
}
public void doWidget(String msg, Config cfg) {
// Does a bunch of stuff and hits a database.
}
}
I'd like to write a simple unit test that stubs the doWidget(String,Config) method (so that it doesn't actually fire and hit the database), but that allows me to verify that calling doBuzz(String) ends up executing doWidget. Mockito seems like the right tool for the job here.
public class FizzConfiguratorTest {
#Test
public void callingDoBuzzAlsoCallsDoWidget() {
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)).
thenThrow(new RuntimeException());
try {
fixture.doBuzz("This should throw.");
// We should never get here. Calling doBuzz should invoke our
// stubbed doWidget, which throws an exception.
Assert.fail();
} catch(RuntimeException rte) {
return; // Test passed.
}
}
}
This seems like a good gameplan (to me at least). But when I actually go to code it up, I get the following compiler error on the 2nd line inside the test method (the Mockito.when(...) line:
The method when(T) in the type Mockito is not applicable for the arguments (void)
I see that Mockito can't mock a method that returns void. So I ask:
Am I approaching this test setup correctly? Or is there a better, Mockito-recommended, way of testing that doBuzz calls doWidget under the hood? And
What can I do about mocking/stubbing doWidget as it is the most critical method of my entire FizzConfigurator class?
I wouldn't use exceptions to test that, but verifications. And another problem is that you can't use when() with methods returning void.
Here's how I would do it:
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any()));
fixture.doBuzz("some string");
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES);
This isn't a direct answer to the question, but I ran across it when trying to troubleshoot my problem and haven't since found a more relevant question.
If you're trying to stub/mock an object marked as Spy, Mockito only picks up the stubs if they're created using the do...when convention as hinted at by JB Nizet:
doReturn(Set.of(...)).when(mySpy).getSomething(...);
It wasn't being picked up by:
when(mySpy.getSomething(...)).thenReturn(Set.of(...));
Which matches the comment in MockHandlerImpl::handle:
// stubbing voids with doThrow() or doAnswer() style
This is a clear sign that doWidget method should belong to another class which FizzConfigurator would depend on.
In your test, this new dependency would be a mock, and you could easily verify if its method was called with verify.
In my case, for the method I was trying to stub, I was passing in incorrect matchers.
My method signature (for the super class method I was trying to stub): String, Object.
I was passing in:
myMethod("string", Mockito.nullable(ClassType.class)) and getting:
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
When using a matcher in another parameter, we also need to use one for the string:
myMethod(eq("string"), Mockito.nullable(ClassType.class))
Hope this helps!

Categories

Resources