2

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

LukeSolar
  • 3,795
  • 4
  • 32
  • 39

4 Answers4

5

beforeInsert is called during unit tests. I can verify this in my tests. A couple things to consider:

  1. ensure you use a beforeInsert method, and not a closure. A closure will not work correctly.
  2. 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)
Peter
  • 29,498
  • 21
  • 89
  • 122
  • Using a closure was my issue, which stems from a mailing list reply from Burt in 2010: http://grails.1312388.n4.nabble.com/Read-only-domain-td1461440.html – Joseph Nov 19 '13 at 22:03
0

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!

Amanuel Nega
  • 1,899
  • 1
  • 24
  • 42
0

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.

thomas.han
  • 2,891
  • 2
  • 17
  • 14
0

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()

Rene
  • 55
  • 4
  • The author is explicit: he created an object, tried to save it, and it did not call beforeInsert. – Antoine Dec 05 '11 at 08:24
  • no, as far as I understand the author: calling myObject.save() in test enviroment is causing errors. – Rene Dec 05 '11 at 10:41
  • true. The question in not precise enough anyway. Is it unit or integration tests? Save is only available in integration tests, unless mockDomain was called. – Antoine Dec 05 '11 at 11:26
  • the method was not called (there was no error). it is a unit test (see the question title and I added it to the body too). thanks. – LukeSolar Dec 05 '11 at 11:37
  • I suggest creating an integrationTest and call save() on your object. Or write a a method: myBeforeInsert() and put the code from beforeIsert into it. Then just call myBeforeInsert in beforeInsert. you can then test the code in myBeforeInsert() in a unit test. – Rene Dec 05 '11 at 12:55