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

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.

Related

Is there an alternative to RETURNS_DEEP_STUBS for mocking chained methods with Mockito?

I have a db service save() method which allows method chaining:
#Service
public class Service {
...
public Service save(...) {
...
return this;
}
and this works just great as:
service.save(this).save(that).save(other);
When I come to mock it with Mockito though it breaks unless I use
Service serviceMock = mock(Service.class, RETURNS_DEEP_STUBS);
IIUC though, the use of RETURNS_DEEP_STUBS is considered bad. Is there a better way to mock a class with method call chaining?
Your pattern for save is very similar to a Builder pattern, which makes the question similar to "How to mock a builder with mockito" elsewhere on SO.
Per David Wallace's answer there, you can write an Answer that detects whether the mock is an instance of the return type of the method, and return the mock in only that case. This functionality was also built into the Mockito library as RETURNS_SELF in Mockito 2.0. As with any Answer, you can use this on any specific method call with thenAnswer or as the second parameter of mock to make it the default answer, but bear in mind the Mockito documentation warning that methods with generous return types (e.g. Object) will return the mock whether or not that was intended.

Mockito.when() not working

I am trying to mock a call to a protected method of one of my classes:
import com.couchbase.client.java.view.Stale; // an enum
import com.google.common.base.Optional;
public class MyClass {
public List<String> myList(Optional<Integer> arg1, Optional<Stale> arg2) {
...
}
}
The mock shall be accomplished in the following way:
// Providing types for any() does not change anything
Mockito.when(myClass.myList(Mockito.any(), Mockito.any()).thenReturn(new ArrayList());
Whenever the previous line is executed the actual myList() method is called with null values for arg1 and arg2. Why is the method called, at all? After all, I am trying to avoid any executing thereof...
As Brice mentioned, if your myList method is final, then Java skips virtual method dispatch and will call the original object (not your mock).
If you are spying on an actual class, it is expected behavior that when will call the actual object as part of the stub: after all, in the expression when(foo.bar()) Java doesn't know anything special about when and assumes that it cares about the return value) of foo.bar(), not the call itself. (I walk through the stubbing process in the "Implementation details" section of my answer here.)
This syntax is better for spies:
doReturn(new ArrayList()).when(myClass).myList(any(), any());
Because this different when method receives an object, Mockito can prepare the object to do nothing during the stubbing, which avoids any spurious calls to your myList method.
Although Jeff's answer did not show a workaround for my problem it pointed me into the right direction.
After changing the mocking behaviour to doReturn... I suddenly got an error message. This message told me that myClass is not a mock which makes sense since you can only mock (or stub?) methods of mocked or spied objects. So as Jeff's answer indicates and is explained in the documentation of mockito I created a partial mock of MyClass with
MyClass myClass = Mockito.spy(new MyClass());
With this partial mock Jeff's approach to method mocking suddenly worked (mine still does not and should therefore be avoided).
So: Thank you, Jeff!

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.

Grails unit test for domain class insertBefore

How can I test the initBefore method of Groovy Domain-Classes with a unit test in Grails?
I created the dummy object but the beforeInsert-method is not called until myObject.save() is invoked and save is unavailable in the testing environments.
Edit: its a unit-test. there is no error, but the method beforeInsert is not called
beforeInsert is called during unit tests. I can verify this in my tests. A couple things to consider:
ensure you use a beforeInsert method, and not a closure. A closure will not work correctly.
it is called when the object is flushed, so perhaps you are having silent save errors beforehand. In your test when you save the object do .save(flush: true, failOnError: true)
Do you want test if the beforeInsert method is being called or the logic of beforeInsert is correct?
If you want to test if beforeInsert is being called the test class should extend the GrailsUnitTestCase. Do so should give you mocking capabilities and add all the methods like save() and validate(). You can verify if the mocked object called the beforeInsert method or not when you do a save().
If you are testing the logic of beforeInsert then you don't need to mock it. You can create the object and test the logic just like other unit test.
Hope this helps.
Just creat a domain object and save() it. Then check whether or not the "beforeInsert" manipulated your Object.
save() is available in the testing enviroments. Please show your Stacktrace when calling myDomainobject.save()
I had the same exact problem! In GORM (at least until the current version) the save method does not take effect immediately just because it is called! If you want it to take effect right away you need to specify flush:true like this domain.save(flush:true).
it says here http://grails.org/doc/2.2.x/ref/Domain%20Classes/save.html
The save method informs the persistence context that an instance
should be saved or updated. The object will not be persisted
immediately unless the flush argument is used:
To answer your question, beforeInsert is not called until the save is persisted (save takes effect) therefor you should invoke save with flush to test beforeInsert and beforeUpdate methods.
Hope this helps!

Is verify called automatically on Groovy's MockFor

According to the javadocs, Groovy's MockFor object always ends with a verify. Its StubFor docs say calling verify is up to the user. I read that as saying that verify will automatically be called on the MockFor object. However, in looking at the groovy samples that use MockFor on a Java object (http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/test/groovy/mock/interceptor/MockForJavaTest.groovy), they call verify explicitly. I've found in my tests that I need to do the same. Are the docs just incorrect or maybe I'm misunderstanding. Any help would be appreciated.
thanks,
Jeff
According to the docs (http://groovy.codehaus.org/Groovy+Mocks), the instance-style mocking that's invoked with the proxyInstance() method (for Groovy) or the proxyDelegateInstance() method (for Java, as in the example you referenced) does indeed require an explicit call to verify.
It's the class-style mocking -- which is invoked by passing in a closure to the .use method -- that does an implicit verify. That's the case for both Mock and Stub.
My understanding of the difference between a Mock and a Stub is that it's a matter of what gets verified when verify is called, not how it's called. A mock validates that events happen in a certain order while a stub only cares that events happen a certain number of times.

Resources