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.
Related
I'm reading the mocking capability of minitest.
require "minitest/autorun"
mock = MiniTest::Mock.new
mock.expect(:use_any_string, true, [String])
mock.use_any_string("foo")
## mock.use_any_string(1)
## MockExpectationError: mocked method :use_any_string called with unexpected arguments [1]
## I do not understand the purpose for this
mock.verify
So I do not understand the purpose of using mock.verify since the trying to pass any another type(to use_any_string) other than String result in mock expectation error.
So why should one use assert mock.verify then?
You are right, you cannot set anything else to the configured mock, but if your mock is not called at all, then you can find out with mock.verify. So if your method under test should call the mocked method, you should verify that it was called at all.
You are correct, mock.expect(:use_any_string, true, [String]) will cause the test to fail if the expected call is not made on the mock.
However using mock.verify depends on how you compose your test. In your example you are explicitly calling the method you are testing with mock.use_any_string("foo") so there is no need to also call mock.verify.
You could get into a scenario where you are not making this call explicitly, or are expecting the mock to have had calls made at a certain time. These scenarios would take advantage of mock.verify calls.
(Another note, minitest has recently introduced assert_mock which can be used instead of mock.verify)
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.
I am mocking an interface array which throws java.lang.IllegalArgumentException: Cannot subclass final class class.
Following are the changes I did.
Added the following annotations at class level in this exact order:
#Runwith(PowerMockRunner.class)
#PrepareForTest({ Array1[].class, Array2[].class })
Inside the class I am doing like this:
Array1[] test1= PowerMockito.mock(Array1[].class);
Array2[] test2= PowerMockito.mock(Array2[].class);
and inside test method:
Mockito.when(staticclass.somemethod()).thenReturn(test1);
Mockito.when(staticclass.somediffmethod()).thenReturn(test2);
Basically I need to mock an array of interfaces.
Any help would be appreciated.
Opening up another perspective on your problem: I think you are getting unit tests wrong.
You only use mocking frameworks in order to control the behavior of individual objects that you provide to your code under test. But there is no sense in mocking an array of something.
When your "class under test" needs to deal with some array, list, map, whatever, then you provide an array, a list, or a map to it - you just make sure that the elements within that array/collection ... are as you need them. Maybe the array is empty for one test, maybe it contains a null for another test, and maybe it contains a mocked object for a third test.
Meaning - you don't do:
SomeInterface[] test1 = PowerMock.mock() ...
Instead you do:
SomeInterface[] test1 = new SomeInterface[] { PowerMock.mock(SomeInterface.class) };
And allow for some notes:
At least in your code, it looks like you called your interface "Array1" and "Array2". That is highly misleading. Give interfaces names that say what their behavior is about. The fact that you later create arrays containing objects of that interface ... doesn't matter at all!
Unless you have good reasons - consider not using PowerMock. PowerMock relies on byte-code manipulation; and can simply cause a lot of problems. In most situations, people wrote untestable code; and then they turn to PowerMock to somehow test that. But the correct answer is to rework that broken design, and to use a mocking framework that comes without "power" in its name. You can watch those videos giving you lengthy explanations how to write testable code!
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.
In my attempt to mock an object in Groovy using the mock.interceptor package:
def mock = new MockFor(TheClass);
mock.demand.theMethod{ "return" }
mock.use {
def underTest = new TheClass()
println underTest.theMethod()
}
The problem I have is when creating TheClass() in the use{ block, it uses the actual constructor which, in this circumstance, I'd rather it not use. How can I create an instance of this class so I can test the method I do care about, theMethod, without needing to use the constructor?
Using EasyMock/CE, mocks can be made without using the constructor, but am curious how to achieve that in Groovy.
I recently saw a presentation by the author of GMock and it has some hooks to allow "constructor" mocking which I think is what you are after.
e.g.
def mockFile = mock(File, constructor('/a/path/file.txt'))
This library differs from that "built in" to groovy, however it looked very well written, with some thought put into the kinds of things you want to mock and more importantly the error messages you would get when tests should fail.
I think this is what you are after. I would say use constructor mocking with care - it could be a smell that you should inject a Factory object, but for some things it looked to work well.
You can use the interceptConstruction flag when calling MockFor, see
MockFor.