Describe Mockito sample code - mockito

In the http://mockito.org/ website the following sample code is given to describe the usage of the mockito framework. However i am not able to understand what the following code is trying to test. Please comment on the following code as what is it exactly testing. If it is testing the add method of the List, what does it expect?
import static org.mockito.Mockito.*;
// mock creation
List mockedList = mock(List.class);
// using mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one");
mockedList.clear();
// selective, explicit, highly readable verification
verify(mockedList).add("one");
verify(mockedList).clear();

In your case, you've a test preparation
// mock creation
List mockedList = mock(List.class);
a test execution
// using mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one");
mockedList.clear();
and a test verification (without mockito mostly done with something like assertEquals)
// selective, explicit, highly readable verification
verify(mockedList).add("one");
verify(mockedList).clear();
The last block (the test verifaction) is testing, if
the add method of the mockedList was called with a parameter that equals the String "one"
the clear method of the mockedList was called
It is just a basic demo of how the interaction with a mocked class can be verified (since you cannot verify the contents of the List because it has been mocked and the calls of add("one") and clear() don't change the contents of the List).

Related

Spock framework: what is the purpose of Spies vs. a using real object or Mock?

From the documentation:
A spy is always based on a real object. Hence you must provide a class type rather than an interface type, along with any constructor arguments for the type. If no constructor arguments are provided, the type’s default constructor will be used.
Method calls on a spy are automatically delegated to the real object. Likewise, values returned from the real object’s methods are passed back to the caller via the spy.
Also:
When stubbing a method on a spy, the real method no longer gets called:
subscriber.receive(_) >> "ok"
Instead of calling SubscriberImpl.receive, the receive method will now simply return "ok".
If a spy is just an interface layer between a real object and the caller, why not just use the real object? What does using a spy offer that using the real object or a Mock do not?
It seems to be in this void between a Mock and a real object to me.
Spies can be used in different scenarios. However, it is good if you can implement your tests without resorting to spies.
(Think twice before using this feature. It might be better to change the design of the code under specification.)
They can be used to verify that a method was called without mocking the method itself
You can stub out calls that you don't want to happen
You can use partial mocks to test the object itself
// this is now the object under specification, not a collaborator
def persister = Spy(MessagePersister) {
// stub a call on the same object
isPersistable(_) >> true
}
when:
persister.receive("msg")
then:
// demand a call on the same object
1 * persister.persist("msg")
Example and quote are from the docs # http://spockframework.org/spock/docs/1.1/all_in_one.html#Spies
In my practice I prefer to use a real objects as much as possible. In case when only one method is to be mocked I still use a real object but with overridden needed method:
MyDomainClass myRealObjectWithMockedMethod = new MyDomainClass() {
#Override
Object doSomething() {
return "hard coded or mocked result";
}
}
// test what you need
myRealObjectWithMockedMethod.action();
Note, this way works only of overridden method is not final. Otherwise Spy will help to define a behavior of this method.
A spy offers the possibility to use the original object but also mock out one method. For example you have a class where you want to test the implementation of the toString() method. But this calls an long running method which needs some external access like a database. In this case you use a spy and let your long running method return some test string and then use the toString from the original object.
Or like the spock example the method subscriber.receive maybe needs a server which sends out asynchronous messages. To write an test for subscriber not relying on the server or to handle asynchronous complexity you let the spy return ok and can easily test your methods which will rely on a server ok.

Mockito isNotNull passes null

Thanks in advance for the help -
I am new to mockito but have spent the last day looking at examples and the documentation but haven't been able to find a solution to my problem, so hopefully this is not too dumb of a question.
I want to verify that deleteLogs() calls deleteLog(Path) NUM_LOGS_TO_DELETE number of times, per path marked for delete. I don't care what the path is in the mock (since I don't want to go to the file system, cluster, etc. for the test) so I verify that deleteLog was called NUM_LOGS_TO_DELETE times with any non-null Path as a parameter. When I step through the execution however, deleteLog gets passed a null argument - this results in a NullPointerException (based on the behavior of the code I inherited).
Maybe I am doing something wrong, but verify and the use of isNotNull seems pretty straight forward...here is my code:
MonitoringController mockController = mock(MonitoringController.class);
// Call the function whose behavior I want to verify
mockController.deleteLogs();
// Verify that mockController called deleteLog the appropriate number of times
verify(mockController, Mockito.times(NUM_LOGS_TO_DELETE)).deleteLog(isNotNull(Path.class));
Thanks again
I've never used isNotNull for arguments so I can't really say what's going wrong with you code - I always use an ArgumentCaptor. Basically you tell it what type of arguments to look for, it captures them, and then after the call you can assert the values you were looking for. Give the below code a try:
ArgumentCaptor<Path> pathCaptor = ArgumentCaptor.forClass(Path.class);
verify(mockController, Mockito.times(NUM_LOGS_TO_DELETE)).deleteLog(pathCaptor.capture());
for (Path path : pathCaptor.getAllValues()) {
assertNotNull(path);
}
As it turns out, isNotNull is a method that returns null, and that's deliberate. Mockito matchers work via side effects, so it's more-or-less expected for all matchers to return dummy values like null or 0 and instead record their expectations on a stack within the Mockito framework.
The unexpected part of this is that your MonitoringController.deleteLog is actually calling your code, rather than calling Mockito's verification code. Typically this happens because deleteLog is final: Mockito works through subclasses (actually dynamic proxies), and because final prohibits subclassing, the compiler basically skips the virtual method lookup and inlines a call directly to the implementation instead of Mockito's mock. Double-check that methods you're trying to stub or verify are not final, because you're counting on them not behaving as final in your test.
It's almost never correct to call a method on a mock directly in your test; if this is a MonitoringControllerTest, you should be using a real MonitoringController and mocking its dependencies. I hope your mockController.deleteLogs() is just meant to stand in for your actual test code, where you exercise some other component that depends on and interacts with MonitoringController.
Most tests don't need mocking at all. Let's say you have this class:
class MonitoringController {
private List<Log> logs = new ArrayList<>();
public void deleteLogs() {
logs.clear();
}
public int getLogCount() {
return logs.size();
}
}
Then this would be a valid test that doesn't use Mockito:
#Test public void deleteLogsShouldReturnZeroLogCount() {
MonitoringController controllerUnderTest = new MonitoringController();
controllerUnderTest.logSomeStuff(); // presumably you've tested elsewhere
// that this works
controllerUnderTest.deleteLogs();
assertEquals(0, controllerUnderTest.getLogCount());
}
But your monitoring controller could also look like this:
class MonitoringController {
private final LogRepository logRepository;
public MonitoringController(LogRepository logRepository) {
// By passing in your dependency, you have made the creator of your class
// responsible. This is called "Inversion-of-Control" (IoC), and is a key
// tenet of dependency injection.
this.logRepository = logRepository;
}
public void deleteLogs() {
logRepository.delete(RecordMatcher.ALL);
}
public int getLogCount() {
return logRepository.count(RecordMatcher.ALL);
}
}
Suddenly it may not be so easy to test your code, because it doesn't keep state of its own. To use the same test as the above one, you would need a working LogRepository. You could write a FakeLogRepository that keeps things in memory, which is a great strategy, or you could use Mockito to make a mock for you:
#Test public void deleteLogsShouldCallRepositoryDelete() {
LogRepository mockLogRepository = Mockito.mock(LogRepository.class);
MonitoringController controllerUnderTest =
new MonitoringController(mockLogRepository);
controllerUnderTest.deleteLogs();
// Now you can check that your REAL MonitoringController calls
// the right method on your MOCK dependency.
Mockito.verify(mockLogRepository).delete(Mockito.eq(RecordMatcher.ALL));
}
This shows some of the benefits and limitations of Mockito:
You don't need the implementation to keep state any more. You don't even need getLogCount to exist.
You can also skip creating the logs, because you're testing the interaction, not the state.
You're more tightly-bound to the implementation of MonitoringController: You can't simply test that it's holding to its general contract.
Mockito can stub individual interactions, but getting them consistent is hard. If you want your LogRepository.count to return 2 until you call delete, then return 0, that would be difficult to express in Mockito. This is why it may make sense to write fake implementations to represent stateful objects and leave Mockito mocks for stateless service interfaces.

SoapUI defining a library of reusable methods

I'm running into copy-pasting a lot of code at the moment in my SoapUI projects, and thought I'd have some sort of library of helper functions that can carry out most of my tasks.
So I have a test suite for this, and the code itself is in a Groovy Script test step in this test suite. The idea is that I make my helper methods available to the context I'm in (a REST test request step).
It instantiates fine and all that, but the problem is that when I want to invoke run(testRunner, context), I am not having access to the testRunner property. I've read something about that this is how it is.
Anyone know a way around this?
I am using the same method as you for script library. I used the method described by Kerry Doan at http://www.doan.me/script-library-in-soapui-free.aspx
When i tried to access this script library from project load script i did not have access to the testRunner so i created the testRunner object and as i did not have access to the context object i had to create that too.
Check out the code below.
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
import com.eviware.soapui.support.types.StringToObjectMap
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext
//to create the testRunner object I need a testCase object and a new StringToObjectMap
//I initially used the test case in the script library but as i needed the
//testRunner object to the test case being executed so i created the object to
//the test case being executed.
//I did not want to worry about test suite or test case names so i used their index
//assuming that there will be at least one test suite and at least one test case when
//this script is run
testCase = project.getTestSuiteAt(0).getTestCaseAt(0)
tcRunner = new WsdlTestCaseRunner( testCase, new StringToObjectMap() );
//A context is essentially a WsdlTestRunContext object and as you can see below all i
//have done to create that is pass it a test step object which was obtained by using index
//rather than name.
tStep = testCase.getTestStepAt(0)
tcContext = new WsdlTestRunContext(tStep)
//my script library is in a seperate project called `Script Library` and all the
//groovy scripts are in a test suite called `Script Library`
scripts = project.workspace.projects["Script Library"].testSuites["Script Library"];
scripts.testCases["Scripts"].testSteps["runTest"].run(tcRunner, tcContext);

writing unit test using mockito

I am writing unit tests in java using mockito.
This is the statement that I am trying to test.
final Map<EntityKey, Element<Movie>> resultMap = Watcher.watch(movies);
movies is Set of movie names which is a key to identify a movie.
I mocked watcher class
final Watcher<Movie> watcher = mock(Watcher.class);
Mockito.when(watcher.watch(Matchers.any(Set.class))).thenReturn()
what to include in "thenReturn"??
In the thenReturn function you need to pass an object of the same type as the method you are mocking's return type.
When this method is then called on that object, it will return the object you passed to thenReturn instead of actually going into the function.
This is the core concept behind mocking.
Having said that. If you are trying to test the Watcher.watch method then you probably don't want to mock it anyway. You should only mock those classes you are NOT testing.
You would need to make a Map<EntityKey,Element<Movie>> that would be suitable for use in the rest of the test. I'm not quite sure what your test is actually trying to assert, but whatever it is, choose the Map accordingly. Your Map object is what you want to return from thenReturn.

Wanted but not invoked: However, there were other interactions with this mock:

Wanted but not invoked: However, there were other interactions with this mock:
This is a mockito error you would catch when trying to verify the invocation on an object on specific method, but what happens is you have interacted with other method of that object but not the one mentioned.
If you have an object named CustomerService and say it has two methods named saveCustomer() and verifyExistingCustomer(),
and your mockito looks something like verify(customerService, atleast(1)).verifyExistingCustomer(customer), but in your actual service you called the saveCustomer() at least one.
Any idea how to resolve this ?
From what you are describing, it looks like you are telling your mocks that you are expecting verifyExistingCustomer() to be called but you are not actually calling it.
You should probably look at your test design, specifically ensuring that you can (via mocking) isolate your tests to test each method individually.
If there is something in your code that decides whether to call saveCustomer() or verifyExistingCustomer() then you should try to mock the data that the code inspects so that you can test each individually.
For example if your code looked like this:
if (customer.getId() == 0) {
saveCustomer(customer);
} else {
verifyExistingCustomer(customer);
}
Then you could have two separate tests that you could isolate by setting a zero value and non-zero value for the id in customer.
If you'd like to share your code I could probably give you a better example.

Resources