easymock - mocking to use anyObject as parma of void setter method - java

Using EasyMock, how can I create the mock of the following class's process method? I want to create a mock which can accept any object of type MyObject.class.
public class Custom {
public void process(MyObject obj){
//code
}
}
I know how to do it if the method returns something, but with a void method I am not able to get my head around it.

Here's how to expect a call on a void method
Custom mock = EasyMock.createMock(Custom.class); // create the mock
mock.process(EasyMock.anyObject(MyObject.class)); // invoke the method
EasyMock.expectLastCall(); // register it as expected
EasyMock.replay(mock); // set the state
mock.process(new MyObject()); // invoke the method in the test
EasyMock.verify(mock); // verify the call

In order to mock a void method you simply call it on the mock object before calling replay.
#Test
public void testSomething() {
Custom mock = createMock(Custom.class);
mock.process(any(MyObject.class);
replay(mock);
// Your test comes here
// Optional - check the process was called
verify(mock);
}

Related

How to mock a method with a return value if there is a void method inside this method

I am testing a class that has a testable method (the method itself below) with a return value.
Using Mockito I am having a problem. Problem with void method roomDao.updateData(outData);
public IEntity getData(SimBasket<DataEntity, SimRequest> request) {
Entity outData = converterData.convertNetToDatabase(request);
roomDao.updateData(outData);
return outData;
}
Here is my test code:
#Test
public void getData() {
simRepo = new SimRepo();
Mockito.when(simRepo.getData(request)).thenReturn(new Entity());
}
Error log:
org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue:
'updateData' is a void method and it cannot be stubbed with a return value!
Voids are usually stubbed with Throwables:
doThrow(exception).when(mock).someVoidMethod();
I don't seem to really understand how to fix this, since the void method is inside a method with a return value.
instead of new SimRepo() try mock it by using Mockito's mock method:
#Test
public void getData() {
SimRepo simRepo =Mockito.mock(SimRepo.class);
Mockito.when(simRepo.getData(request)).thenReturn(new Entity());
}
Update:
If you also want to count the number of times this mock method called use this:
// this will check if mock method getData() with parameter `request` called exactly 1 times or not.
Mockito.verify(simRepo, Mockito.times(1)).getData(request);

How to mock void method using EasyMock and then how to test it using assert?

I need to unit test a function, which makes an inner call of another void method.
Class TestClass {
public void testMethod() {
someOtherClass.testMethod(); // This is void method
}
}
I need to mock someOtherClass.testMethod() and then verify testMethod of TestClass using assert.
Sorry for my post if it is confusing. Let me make it more clear. My intention is -
public void testMethodTest() {
TestClass tC = new TestClass(); SomeOtherClass obj = EasyMock.createNiceMock(SomeOtherClass.class);
tC.set(obj);
obj.testMethod();
EasyMock.expectLastCall().andAnswer(new IAnswer() {
public Object answer() { // return the value to be returned by the method (null for void)
return null;
}
});
EasyMock.replay(obj);
tC.testMethod(); // How to verify this using assert.
}
What you wrote is working. However, it is overly complicated and you are not verifying that the void method was actually called. To do that, you need to add EasyMock.verify(obj); at the end.
Then, one important thing is that if you call a void method before the replay, it records a call. No need to add an expectLastCall. Also, you could have used expectLastCall().andVoid() instead of the IAnswer.
Here is how I would write it:
#Test
public void testMethodTest() {
TestClass tC = new TestClass();
SomeOtherClass obj = mock(SomeOtherClass.class); // no need to use a nice mock
tC.set(obj);
obj.testMethod();
replay(obj);
tC.testMethod();
verify(obj); // Verify testMethod was called
}

Use Mockito to Stub methods in the same class as the class under test (CUT)

I am trying to test some legacy code using Mockito, and the method is a of type void.
I have stubbed out a lot of the calls to methods in other classes, this works fine.
However, I also need to be able to stub out certain calls to other methods inside the same class.
Currently this is not working.
e.g. My Class is like below:
public class Test {
public Test(dummy dummy) {
}
public void checkTask(Task task, List <String> dependencyOnLastSuccessList) throws TaskException {
callToOtherClass.method1 // This works fine, I can stub it using mockito
updateAndReschedule(Long id, String message) // call to method in same class, I cannot stub it
}
public void updateAndReschedule(Long id, String message) {
//method logic.....
}
}
This is my testClass showing what I have at the minute:
#Test
public void testMyMethod() {
Test testRef = new Test(taskJob);
Test spy = spy (testRef);
// when a particular method is called, return a specific object
when(callToOtherClass.method1).thenReturn(ObjectABC);
//doNothing when my local method is called
doNothing().when(spy).updateAndReschedule(1, "test");
//make method call
spy.checkTask(ts, taskDependencies);
}
You should instantiante testRef as follows:
Test testRef = new Test(taskJob) {
public void updateAndReschedule(Long id, String message) {
//do nothing
}
};
No need for the spy.
In my opinion the spy object instead of mock.
Spy is a mock created as a proxy to an existing real object; some methods can be stubbed, while the unstubbed ones are forwarded to the covered object
The spy is more elegant than anonymous implementation of chosen methods
Look at the example:
Mockito: Trying to spy on method is calling the original method
the nice article about mockito You can read
http://refcardz.dzone.com/refcardz/mockito

Mocking static method that is called multiple times

I have a static method, that is used in multiple places, mostly in static initialization block. It takes a Class object as parameter, and returns the class's instance.
I want to mock this static method only when particular Class object is used as parameter. But when the method is called from other places, with different Class objects, it returns null.
How can we have the static method execute actual implementation in case of parameters other than the mocked one?
class ABC{
void someMethod(){
Node impl = ServiceFactory.getImpl(Node.class); //need to mock this call
impl.xyz();
}
}
class SomeOtherClass{
static Line impl = ServiceFactory.getImpl(Line.class); //the mock code below returns null here
}
class TestABC{
#Mocked ServiceFactory fact;
#Test
public void testSomeMethod(){
new NonStrictExpectations(){
ServiceFactory.getImpl(Node.class);
returns(new NodeImpl());
}
}
}
What you want is a form of "partial mocking", specifically dynamic partial mocking in the JMockit API:
#Test
public void testSomeMethod() {
new NonStrictExpectations(ServiceFactory.class) {{
ServiceFactory.getImpl(Node.class); result = new NodeImpl();
}};
// Call tested code...
}
Only the invocations that match a recorded expectation will get mocked. Others will execute the real implementation, when the dynamically mocked class is called.

How to mock a void return method affecting an object

I am writing unit tests for my application and I was wondering if it is possible for the Mockito framework to affect an object that is passed into a method that returns void of a mocked class. For instance, calling a mocked validation class that contains a method that returns void but tracks various changes and metadata via an object passed in as an argument. .
public GetCartItemsOutput getCartItems(GetCartItemsInput getCartItemsInput) {
CartItemsFilter cartItemsFilter = new CartItemsFilter();
validator.validateCartItemsInput(getCartItemsInput, cartItemsFilter); ...
I mocked the validator class for my other tests but for this one I need mock the changes to the cartItemsFilter object which I do not know how to do.
The answer is yes, you can, and there are basically two levels of doing this, based on the need of your test.
If you merely want to test the interaction with the mocked object, you can simply use the verify() method, to verify that the void method was called.
If your test genuinely needs the mocked object to modify parameters passed to it, you will need to implement an Answer:
EDITED to show proper form of using Answer with void method
doAnswer(new Answer() {
#Override
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null; // void method, so return null
}
}).when(mock).someMethod();
In Java 8+, the above is simplified with a lambda:
doAnswer(invocation-> {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null;
}).when(mock).someMethod();
To add to Kevin Welker's answer,
if your MyClass is a custom class, then define a equals/hashcode method in it, so that Mockito can use it to match to the method call exactly.
In my case, "MyClass" was in a third-party API, so I had to use the method "any" as below -
doAnswer(new Answer() {
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
((MyClass)args[0]).myClassSetMyField(NEW_VALUE);
return null; // void method, so return null
}
}).when(mock).someMethod(any(MyClass.class));
ArgumentCaptor might also help.
Here's a snippet found from here:
ArgumentCaptor<GetCartItemsInput > argument = ArgumentCaptor.forClass(GetCartItemsInput .class);
verify(mock).getCartItems(argument.capture());
assertEquals(cartItemsFilter, argument.getValue());

Categories

Resources