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.
Related
It seems that, when I use thenReturn like this:
when(abc.call()).thenReturn(a).thenReturn(b),
I expect:
verify(abc, times(2)).call()
instead, the method seems only get called once, I am a little confused(my test work as expected, the mock seems return the value I expected), but for the invocation times, I don't know if I am getting the wrong result, or it's a expected behavior of the Mockito?
when() is mocking the abc.call() method which has to produce a certain return type. If the method is called once, it will return the value also once, so the stubbing for method invocation is done only once hence the verify only recognizes one call.
You need to customize your function so that the stub(abc.call()) gets called more than once.
You can follow this thread for implementing multiple stubs
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 would like to know is the thing in the description possible and how to do it.
I know you can call original method and then do the Answer like this:
when(presenter, "myMethod").doAnswer(<CUSTOMANSWER>)
but I would like to order them differently, first do CUSTOMANSWER and then call the original method.
For followers, it's actually possible to doAnswer and callRealMethod at the same time...
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
invocationOnMock.callRealMethod(); // this one
return null;
}
}).when(subject).method(...);
You won't ever see when(...).doAnswer() in Mockito. Instead, you'll see either of the following, which includes the "call real method" behavior you're describing. As usual with Mockito stubbing, Mockito will select the most recent chain of calls that matches the method call and argument values in the invocation, and do each action in the chain once until the final action (which it will do for all calls afterwards.
// Normal Mockito syntax assuming "myMethod" is accessible. See caveat below.
when(presenter.myMethod()).thenAnswer(customAnswer).thenCallRealMethod();
// ...or...
doAnswer(customAnswer).doCallRealMethod().when(presenter).myMethod();
That said, there's a deficiency in the PowerMockito API that makes this difficult, because after the first doAnswer call all subsequent calls you get a normal Mockito Stubber instance rather than a PowerMockitoStubber instance. The bug 599 was misinterpreted, so for the time being you'll still have to make the cast yourself.
((PowerMockitoStubber) doAnswer(customAnswer).doCallRealMethod())
.when(presenter, "myMethod");
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!