I am using junit to run a few unit tests. One of these calls a method in an object that I mock using mockito like;
#Mock
private MyClass myClass;
I then set up mockito to do something like
Mockito.when(myClass.foo(Mockito.any()).thenReturn(bar);
Now myClass.foo actually takes another one of my classes (say class Person) as an argument and what I would like to do is something like this
Mockito.when(myClass.foo(Person parson)).thenDo(person.setName("Name")).thenReturn(bar);
That is of course pseudo code but I hope it illustrates what I am trying to do. Is this possible?
You need to use thenAnswer or its twin doAnswer method.
See Mockito : doAnswer Vs thenReturn
You should use thenReturn or doReturn when you know the return value at the time you mock a method call. This defined value is returned when you invoke the mocked method.
Answer is used when you need to do additional actions when a mocked method is invoked, e.g. when you need to compute the return value based on the parameters of this method call.
If your answers become too complicated, consider using a fake instead of a mock.
In this case if your goal is to set field of Person object you can do that before or after the line:
Mockito.when(myClass.foo(Mockito.any()).thenReturn(bar);
doAnswer() would help do operations based on input, but operations would be performed on copy of arguments not the original arguments.
Related
This seems like it should be simple but I'm running around in circles.
I have:
#Mock
SimpleAbstractCacheWithInputs<Key, Value, Inputs> underlyingCache;
I then try to set up a call on the cache in setup():
when(underlyingCache.getOrCreate(usdgbpKey)).thenReturn(usdgbpCfi);
But this throws a null pointer exception from within getOrCreate() because it's trying to execute the actual code in the real object, not mocked at all, and that isn't set up.
But I don't want to ever run getOrCreate real code, I just want it to return the mocked value!
So how do I do this without having to set up everything inside underlyingCache that I'm never going to use in order to mock this one method call?
If you were concerned about the behavior of a spy or already-stubbed object, I would recommend this syntax, which doesn't rely on calling the mocked object:
doReturn(usdgbpCfi).when(underlyingCache).getOrCreate(usdgbpKey);
...but that all seems right. If you're using the #Mock annotation, then the entire object should be mocked, or null if you've forgotten a Mockito runner/rule/initialization.
There are a few cases where mocking would fail and you get the actual behavior instead:
If the method is final, because then Mockito can't override the method (through a proxy).
If the class is final, because then Mockito can't override the class (through a proxy).
If the class has complicated access semantics, such as a public nested class that accesses private parent methods, because the Java compiler may rewrite the method call through a synthetic method that Mockito can't (easily) mock.
So I'm trying to test a method methodUnderTest which is something like this:
methodUnderTest{
//Other stuff that works nice
this.setterMethod(OtherClass.methodThatErrors(arg1));
}
So I'm trying to avoid that static method call methodThatErrors.
What I'm doing so far:
ClassUnderTest spy = Mockito.spy(objectOfClassUnderTest);
Mockito.doNothing().when(spy).setterMethod(Mockito.any(OtherClass.class));
However this does not work, the method is still being called. I would've thought that it shouldn't call the argument method at all because I've written any for the argument of setterMethod. So how can I prevent this call using Mockito, not PowerMockito.
Edit:
So I managed to mock it by moving the static method call like so:
methodUnderTest{
this.extraSetterMethod(arg1);
}
extraSetterMethod(arg1){
this.setterMethod(OtherClass.methodThatErrors(arg1));
}
I don't really like this solution because it's adding several extra lines of code (even more with javadoc) which just makes the class messier.
The problem here is that the value is coming directly from the static method, and not the setter itself. Whatever value it's getting is coming from the real invocation of the method itself. Mocking out the call to the setter has no effect; it's not the result of the setter that's in error.
This is a scenario in which you have to make a hard decision:
Introduce a parameter to the method so that the call can be easier to mock, or
Use PowerMockito to mock out the call.
I strongly encourage the latter, especially if you're dealing with a legacy code base which is not very forgiving to a signature change.
EasyMock has a function called createMockBuilder with which someone can specify a partially mocked class.
Is it possible to do the same with Mockito?
For example in EasyMock some can do the following :
classA mockedA = EasyMock.
createMockBuilder(A.class).
withConstructor(B.class,C.class).
withArgs(b,null).
addMockedMethod("print").
createMock();
Is it possible to do the same with Mockito?
Mockito does it a little differently from EasyMock. For instance, whereas in EasyMock, you decide which member functions you want mocked:
EasyMock.createMockBuilder(A.class).addMockedMethod("foo");
in Mockito, all member functions are mocked by default, and you can specify when you want to call an underlying function:
A a = Mockito.mock(A.class);
Mockito.when(a.foo()).thenCallRealMethod();
If you're wanting to mock only a few member functions with Mockito, I can think of two ways to proceed: The example above, and spying.
A a = Mockito.spy(A.class);
Mockito.when(a.foo()).thenReturn("ret");
a.bar(); // Calls the real A.bar() function.
Using a spy, member functions are not mocked by default, but can be mocked selectively. See more information here: http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#spy
I'm trying to wrap my head around mockito and was wondering how I would test if a method calls a method!
So here is class with its method inside it:
public class RegisterController {
public void regHandle(UserDataObject user1){
ValidateRegisterInputController validate = new ValidateRegisterInputController();
validate.validateInputHandle(user1); }
How would I test that regHandle(UserDataObject) calls validate.validateInputHandle(user1); ?
I'm sure this is a super simple test, but I really can't figure out how to test this.
There are various ways of writing a test for a method which instantiates some other class. I wrote about two of them in my article on the Mockito wiki, at http://code.google.com/p/mockito/wiki/MockingObjectCreation
Both the techniques that I describe involve refactoring your code to make it more testable.
You would create a mock of ValidateRegisterInputController and then pass it on construction, then you would do:
Mockito.verify(mock).validateInputHandle(user1).
I strongly suggest you do not do this type of testing though. Instead of that, ask yourself how can you write an unit test that checks that what you wanted to validate was valid.
for example, check that after calling regHandle user1.isValid() is equals to true.
I was thinking, is it possible to mock whole object behavior with EasyMock, but in a way that once declared mock with all expected values and results is used several times without caring about the order of the requests ?
The purpose for this is to create an instance of mock for example in JUnit test #BeforeClass and use it in several #Test methods.
Thank you in advance for any input,
Regards,
P.
If you are not interested in verifying calls to the mock, and your only aim is to ensure that whenever a specific method on the mock is called, it will always return the same desired result, you can configure it using andStubReturn(), e.g.
expect(mock.getMeaningOfLifeUniverseAndEverything()).andStubReturn(42);
I think you're really wanting two things:
The ability to use mocked methods out of order, which is the default easymock (non-strict mode),
The ability to use mocked methods any number of times.
You do the latter like this:
expect(someMock.someMethod()).anyTimes().andReturn(someValue);
If your method will get different arguments each time it is called, you can use the anyObject() method to ignore the provided argument.