I am new in Unit Testing in Java and tried to test a void method using ArgumentCaptor. On the other hand, I have seen that there is another approach called Mockito.doAnswer that can also be used for testing a void method.
In this scene:
1. What are the main purposes of Mockito.doAnswer and ArgumentCaptor?
2. What are the differences between Mockito.doAnswer and ArgumentCaptor and pros/cons of them?
They're completely different things.
DoAnswer is for stubbing. For setting up "fake" behaviour that you want to have occurring when a particular method is called.
ArgumentCaptor is for verification. You use it if you want to check what arguments were passed to a method, during the running of a test.
Related
In my testing of a legacy system, I have found myself having to mock similar classes for different parts of the system I'm increasing test coverage for. I would like to create a helper class for my tests that could call a method that would set up particular mocks and their return values.
Here's an example of a method I have had to create a few times in multiple tests.
public void mockClassINeedToMockToReturn(Boolean bool){
mockStatic(classINeedToMock.class);
when(classINeedToMock.getSuccess(Mockito.any(someClass.class))).thenReturn(bool);
}
I have tried setting this up in a HelperTest.class (in the same project/folder as my tests) and it isn't working. I have included both the following Annotations in the class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({classINeedToMock.class})
I have tried:
Using the methods statically and calling them in my tests. (does not mock)
Creating a HelperTest object and calling the method in my test. (still does not mock)
Having my tests Extend my HelperTest.class and calling the method from in my tests. (Still refuses to mock the class)
I'm sure this is something to do with the way the PowerMockRunner works. So is there a way to make this work? Or should I just come to terms with duplicating these methods throughout my project.
It's the little details.... When looking into it more I noticed the class I was mocking had 2 separate methods.
theClass.method(var1, var2);
theClass.method(var1, List<var2>);
One of my tests was calling the first method, the other was calling the second method. When I ran the second test (only having mocked the first method), it was calling the actual class because that method was not mocked.
After setting up the correct mock with the proper input parameters I could call the method statically and the mock would be created and used appropriately.
This may be a simple question, but I could not find an answer with reasonable search.
I am trying to make a static method return a value more than once in multiple tests. I fail to achieve this with the mocked static method with PowerMock. To put this simply I have a JUnit test #BeforeClass like this
#RunWith(PowerMockRunner.class)
#PrepareForTest(StaticStuff.class)
public class MyTest extends TestCase {
#BeforeClass
public static void init() {
// Mock some stuff
PowerMockito.mockStatic(StaticStuff.class);
Mockito.when(StaticStuff.get()).thenReturn("something");
}
}
Now, this works for the first test accessing the static method, but the rest will receive 'null' (update: or any other value that the "real" method would return). I can fix the problem simply changing the #BeforeClass to #Before, thus making the static mock be recreated for every test. But afaik, this is not the correct way to do this. For this particular case this will do, but I believe there should be a way to provide information that the method may be called "any times".
Actually I understood from the documentation that the same value should be returned "infinite times by default" (but it doesn't. From Mockito documentation: 'Once stubbed, mocked method will always return stubbed value regardless of how many times it is called.'). Also I would expect that stating the amount of calls should be something this simple (but it isn't):
Mockito.when(StaticStuff.get()).thenReturn("something").times(10);
Maybe I am just missing something?
The tests should be independent from each other. If you use JUnit, the order of the tests is not determined at all (see https://github.com/junit-team/junit/wiki/Test-execution-order). I think creating mocks in #BeforeClass is actually a bad practice, since it can cause that the tests are depending on each other. So I would simply recommend to use #Before method to initialize all mocks, and use #BeforeClass only, if you prepare something really common for the tests (like a connection pool or something like that).
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.
In the following example:
Execution execution = mock(Execution.class);
when(execution.getLastQty()).thenReturn(1000.0);
when(execution.getLastPrice()).thenReturn(75.0);
order.onFillReceived(execution);
assertEquals(0, order.getLeavesQty(), 0);
Execution has many other methods that should not be called. Only the two methods that have been mocked should be used within this test and should be called. If any other methods are called, then the test should fail.
How to I tell Mockito to fail if any other methods are called?
The documentation covers this explicitly. You want to call verifyNoMoreInteractions, either after calling verify (as per the docs) or
verify(execution).getLastQty();
verify(execution).getLastPrice();
verifyNoMoreInteractions(execution);
or using ignoreStubs:
verifyNoMoreInteractions(ignoreStubs(execution));
You could try the never method if that fits the use case:
i.e.
verify(execution, never()).someOtherMethod();
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.