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!
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'm wondering,
If in #Before method I'm initializing a mock objects, shouldn't I nullify references to it in #After ? Or would that be redundant? And why?
Not necessary, JUnit creates a new instance of the test per test method.
However if it's static fields it's another story, and proper lifecycle should be implemented, but I strongly advise you to not use static fields in a JUnit test ! Instead think about implementing your own JUnit Runner.
And for TestNG, it's a different story, as TestNG creates a single instance of the test, so you have to be careful there on the lifecycle of the mocks.
"Nullifying" reference doesn't change anything here.
#Before annotated method is ran before each test method. If you are initializing mocks in such method they will be reinitialized before each test. There is a different annotation - #BeforeClass, this annotation causes a method to be executed only once before execution of any test method in that test class. In this case however "nullifying" a reference will not help you because you still need to create a new mock object and assign its reference to your field.
I am seeing an exception when mocking an object that is already under KVO observation. Here is a simplified example that shows the problem:
[sourceObject addObserver:destinationObject forKeyPath:#"stringProperty" options:NSKeyValueObservingOptionNew context:nil];
[OCMockObject partialMockForObject:sourceObject];
[sourceObject removeObserver:destinationObject forKeyPath:#"stringProperty"];
When calling "-removeObserver:forKeyPath:" I get an exception that I am not currently observing the object. If I call "-stopMocking" on the mock before calling "-removeObserver:forKeyPath:" everything works fine.
Both OCMock and KVO dynamically subclass the object and they so they can't work properly together. The only real solution is to modify your tests in such a way to not have to mock the object under observation. Worst case you will have to create your own test subclass to be used while testing.
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.