I'm using EasyMock to do some unit tests and I don't understand the usage of EasyMock.expectLastCall(). As you can see in my code below, I have an object with a method that returns void getting called in some other object's method. I would think that I have to make EasyMock expect that method call, but I tried commenting out the expectLastCall() invocation and it still works. Is it because I passed EasyMock.anyObject()) that it registered it as an expected call or is there something else going on?
MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);
obj.methodThatReturnsVoid(EasyMock.<String>anyObject());
// whether I comment this out or not, it works
EasyMock.expectLastCall();
EasyMock.replay(obj);
// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);
The API doc for EasyMock says this about expectLastCall():
Returns the expectation setter for the last expected invocation in the current thread. This method is used for expected invocations on void methods.
This method returns you the handle of expectation through IExpectationSetters; which gives you ability to validate(assert) that your void method was called or not and related behaviors e.g.
EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();
Detailed API of the IExpectationSetters is here.
In your example you are just getting the handle and not doing anything with it hence you don't see any impact of having or removing the statement. It's very same as you call some getter method or declare some variable and don't use it.
You only need EasyMock.expectLastCall(); when you need to further verify anything other than "That the method was called. (same as setting expectation)"
Say you want to verify how many times the method was called so you will add any of :
EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();
Or say you want to throw an exception
EasyMock.expectLastCall().andThrow()
If you don't care then EasyMock.expectLastCall(); is not required and does not make any difference, your statement "obj.methodThatReturnsVoid(EasyMock.<String>anyObject());" is enough for setting up expectation.
You are missing EasyMock.verify(..)
MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);
obj.methodThatReturnsVoid(EasyMock.<String>anyObject());
// whether I comment this out or not, it works
EasyMock.expectLastCall();
EasyMock.replay(obj);
// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);
// verify that your method was called
EasyMock.verify(obj);
Related
I'm running some unit tests on a methodA of a spied instance of a class (let's say instance is myClass), which uses a helper method (lets call it helper(long num, ObjectA obA, ObjectB obB)) to determine the boolean value of a flag
The parameters of this class are all mocked, the class is instantiated with a spy call, and the method itself is a protected method with 3 parameters. The method is called with every run of methodA. MethodA sets the values of the parameters for the helper method
My question is, is there a way to make, in this specific test, the helper method return true?
I've tried to, using the following:
when(myClass.shouldSetFlag(anyLong(), any(ObjectA.class), any(ObjectB.class))).thenReturn(true);
but every time I get a null pointer exception.
Would really appreciate some insight, thanks!
Since you've provided only one line of code and no stack trace, I assume the NullPointerException is thrown from the shouldSetFlag method.
When you mock the method using when(...) Mockito actually replaces the matchers with default values during the method call in this line (it's still Java code, the method is still called). If you act on ObjectA or ObjectB instances inside the method, the actual code encounters a null reference and the exception is thrown.
From the docs:
Matcher methods like anyObject(), eq() do not return matchers. Internally, they record a matcher on a stack and return a dummy value (usually null).
You can also observe that in the Mockito code, since it's open source.
To work around that use doReturn(...) (see the docs here) - the actual method will not be called while mocking, yet it still will be registered in Mockito.
When using mocks for unit testing, I often encounter the need to check whether a certain method of the mock is invoked with proper arguments. This means that I have to somehow find a way to peek into what gets passed to the method in question. In Spock this can be done using something like:
1 * serviceMock.operate(*_) >> { args ->
def argument = args[0]
assert expectedValue = argument.actualValue
}
With Mockito (and JUnit), the only way I think this can be done is by using doAnswer and verify, something like:
doAnswer(new Answer() {
//check arguments here
}).when(service).operate(any(Data.class));
Then I have to verify that the operation actually gets called with:
verify(service).operate(any(Data.class));
The code above, however, interferes with doAnswer as if it's an actual call to the method in question. How do I work around this so that I can both verify that the method is called, and verify that the arguments it gets are correct?
Mockito verifies argument values in natural java style: by using an equals() method. This is also the recommended way of matching arguments because it makes tests clean & simple.
ArgumentCaptor<Data> argument = ArgumentCaptor.forClass(Data.class);
verify(service).operate(argument.capture());
assertEquals("John", argument.getValue().getDataName());
more refer here
I hope this will be helpful
I have to test a method which invokes two void methods. I just want to check if the two void methods are invoked or not, but the method must be stubbed.
How do I do it? I tried to implement it using Mockito doThrow method, but not success.
doThrow(new RuntimeException()).when(mockedClass).methodName();
Wanted but not invoked: error
How do I solve my problem?
You can verify only calls in mocked stuff, e.g.
Foo bar = Mockito.mock(Foo.class);
ClassToTest testInstance = new ClassToTest(bar);
testInstance.doStuff();
Mockito.verify(bar, times(1)).someMethod(); // will pass if someMethod of Foo class was called in scope of testInstance.doStuff()
I'm not really sure that you should check actual method calls by expecting an exception. Could you provide some code/a bit more details about the context?
You actually need to use verifyMethod on Mockito. Here is someone who had the same issue. The example shown mocks the object, injects it and then checks to see if it was called or not.
Mockito : how to verify method was called on an object created within a method?
I am new to Mockito and I was wondering how I could stub a get/set pair.
For example
public interface Order {
public short getStatus();
public void setStatus(short status);
}
How can I make them behave properly:
if somewhere in a test I invoke setStatus(4); I would like getStatus() to return 4. How can this be done?
Are you stubbing or mocking?
The difference is whether you are verifying behaviour or providing data for a test. You say:
if somewhere in a test I invoke setStatus(4); I would like getStatus() to return 4.
this implies both at the same time. You either want to verify that setStatus() was called with an argument 4.
verify(mockObject).setStatus(4);
or you want to set your mock object to return 4 when getStatus() is called.
when(mockObject.getStatus()).thenReturn(4);
Mockito has some tutorials which explain how to use it for each situation. I suspect you could do both in your test (but have not checked) but this would be a smell to me, as you should ideally only be checking mocking a single thing in your test, everything else should be stubbed. But, as ever, context is everything and so it may be that you need to stub one part of your object so you can verify the behaviour of another part, in which case it would be fine.
Follow the AAA syntax and arrange your test (ie do the setup and have the when clause) then act (ie call the method on the object under test) then do your asserts (ie have your verify statements)
EDIT
it seems that in the newer versions (1.8+) of mockito it may be possible to do what you want, although it is not recommended. You can use a Spy to create a partial mock of an object. In this case you should be able to create a Spy of your actual object, leave the getStatus() and setStatus() methods un-stubbed (so they are actually called and used) and just stub out the other methods (or just verify they were called presumably). You can read about it in section 13 Spying on real objects on this page.
You can set the behavior of the setStatus method so that it updates the behavior of the getStatus method, as follows:
Mockito.doAnswer(invocation -> {
short status = invocation.getArgumentAt(0, Short.class);
Mockito.when(mockOrder.getStatus()).thenReturn(status);
return null;
}).when(mockOrder).setStatus(Mockito.anyShort());
(Disclaimer - EasyMock newb)
According to the documentation (and this post), if I wanted to use EasyMock to generate stub objects, I should use EasyMock.createNiceMock(). A "nice mock" is actually a stub - i.e an object that doesn't participate in validation, just returns values.
However, the following snippet fails for me with an IllegalStateException("missing behavior definition for the preceding method"), on the second foo.translate() line.
Foo foo = EasyMock.createNiceMock(Foo.class);
EasyMock.replay(foo); // added this line
foo.translate("a", "b");
foo.translate("a", "b"); // only the second calls throws an exception
Can anyone explain this, or rather tell me how to use EasyMock to create stubs with zero verbosity (o(number_of_exercised_mock_methods)).
Edit - I've noticed that I'm getting these errors almost always when a debugger is attached, but never when it isn't attached. Any idea how that may be related?
Complementing on Jeff's answer.
From EasyMock's method createNiceMock javadoc:
Creates a mock object that implements the given interface, order checking
is disabled by default, and the mock object will return 0,
null or false for unexpected invocations.
A mock object created by this method don't need any configuration (expected invocations). You just have to create it and "replay it". Example:
ComplicatedObject stub = EasyMock.createNiceMock();
replay(stub);
Any method call is allowed on the created stub (it won't throw an Exception), and they will always return the default value (0, null or false). If you set up an specific invocation expectation, then you'll have to configure it's return value or you'll get an error (that's your case).
If you want to restrict which methods can be executed (making the test fail if an unexpected method is called), them I'm afraid you'll have to create a regular mock, set up every invocation expectation and a return value for each of those.
If your translate method returns a value, you need to setup an expectation for it.
expect(foo.translate("a","b")).andStubReturn(retVal);
You need to call EasyMock.replay(foo). Before you do that your mock object is in a "record state". From EasyMock documentation:
In the record state (before calling
replay), the Mock Object does not
behave like a Mock Object, but it
records method calls. After calling
replay, it behaves like a Mock Object,
checking whether the expected method
calls are really done.
If you with to create a stub object just call createNiceMock followed by replay:
Foo foo = EasyMock.createNiceMock(Foo.class);
EasyMock.replay(foo);
foo.translate("a", "b");
foo.translate("a", "b");