|
Hi,
since 2.0.2/2.0.3 had some changes in the binding area i got problems with some tests (unit-test on domain class with Dependency Injected Service). I got a domain class that has a service injected:
class BalancingDate { ... transient static HolidayService holidayService ... } which is used in a custom validator-constraint of that domain-class. Before I was able do something like the following in my unit-tests: @TestFor(BalancingDate)
class BalancingDateTests { final static DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat('dd.MM.yyyy') final static INIT_VALUES = [ holidayService: new HolidayService(), cashUp: SIMPLE_DATE_FORMAT.parse('01.12.2011').clearTime(), // Thuesday
payout: SIMPLE_DATE_FORMAT.parse('05.12.2011').clearTime(), // Monday ]
/** * Test the simple validation for all mandatory fields
*/ void testSimpleValidation() { BalancingDate instance = new BalancingDate(INIT_VALUES)
if (!instance.validate()) { println instance.errors fail('Simple Validation Failure')
} } } Since (in > 2.0.1) the service is not bound any more with this approach and I get a NPE when
holidayService.getHoliday() is called in the custom validator-constraints. | java.lang.NullPointerException: Cannot invoke method getHoliday() on null object
What is the best way to get around this problem ? Do I really need to explicitly call something like instance.holidayService = new HolidayService()
before I do a instance.validate() ? or alternatively create the instance in a @Before void setUp() { }
method ? Is there a better way to inject a service for domain-class-unit-tests ? Some best practice advice would be really helpful. Thnx, Kosta
|
|
Anybody with a tip, hint or recommendation of how to solve this ?
Thnx, Kosta 2012/4/19 Konstantinos Kostarellis <[hidden email]> Hi, |
|
Hi Kosta,
A couple of things worth trying: 1. define HolidayService with def instead of an explicit class: def holidayService 2. add @Mock annotation to your test: @TestFor(BalancingDate) @Mock(HolidayService) Can't promise this will work but worth a try. On 20 April 2012 14:13, Konstantinos Kostarellis <[hidden email]> wrote: > Anybody with a tip, hint or recommendation of how to solve this ? > > Thnx, > Kosta > > 2012/4/19 Konstantinos Kostarellis <[hidden email]> >> >> Hi, >> >> since 2.0.2/2.0.3 had some changes in the binding area i got problems with >> some tests (unit-test on domain class with Dependency Injected Service). >> >> I got a domain class that has a service injected: >> >> class BalancingDate { >> ... >> transient static HolidayService holidayService >> ... >> } >> >> which is used in a custom validator-constraint of that domain-class. >> Before I was able do something like the following in my unit-tests: >> >> @TestFor(BalancingDate) >> class BalancingDateTests { >> >> final static DateFormat SIMPLE_DATE_FORMAT = new >> SimpleDateFormat('dd.MM.yyyy') >> >> final static INIT_VALUES = [ >> holidayService: new HolidayService(), >> cashUp: SIMPLE_DATE_FORMAT.parse('01.12.2011').clearTime(), // Thuesday >> payout: SIMPLE_DATE_FORMAT.parse('05.12.2011').clearTime(), // Monday >> ] >> >> /** >> * Test the simple validation for all mandatory fields >> */ >> void testSimpleValidation() { >> BalancingDate instance = new BalancingDate(INIT_VALUES) >> if (!instance.validate()) { >> println instance.errors >> fail('Simple Validation Failure') >> } >> } >> } >> >> Since (in > 2.0.1) the service is not bound any more with this approach >> and I get a NPE when >> holidayService.getHoliday() is called in the custom validator-constraints. >> >> | java.lang.NullPointerException: Cannot invoke method getHoliday() on >> null object >> >> What is the best way to get around this problem ? >> >> Do I really need to explicitly call something like >> >> instance.holidayService = new HolidayService() >> >> before I do a instance.validate() ? or alternatively create the instance >> in a >> >> @Before >> void setUp() { } >> >> method ? Is there a better way to inject a service for >> domain-class-unit-tests ? >> Some best practice advice would be really helpful. >> >> Thnx, >> Kosta >> > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
Hi Kosta, When I upgraded an app to Grails 2.0.3 I had to make similar changes to a unit test that was setting a domain service in the constructor. To avoid repeating the service assignment in each test method, I used a test-class level field for the domain object and set the service in a @Before method - something like this:
BalancingDate instance @Before void setUp() { instance = new BalancingDate() instance.holidayService = new HolidayService()
} @Test void testMethod() { ... instance.validate() } Or another option could be to create a test helper method that creates a new instance of BalancingDate with the service assigned, and use the helper method to create any instances used in the test methods.
private BalancingDate createInstance() { BalancingDate instance = new BalancingDate() instance.holidayService = new HolidayService() return instance
} @Test void testMethod() { BalancingDate instance = createInstance() ... } -Craig On Fri, Apr 20, 2012 at 7:44 AM, Alex Anderson <[hidden email]> wrote: Hi Kosta, |
|
Thnx Craig,
thats basically what I did, too. I just hopped there would be some handy little switch or something to make it work for the unit-tests, so I would not have to touch all of them to make them work again.
Unfortunately it seems there is not... @Alex I have tried @Mock but somehow it didn't work for me. Did you get it work for you ?? thnx for the feedback,
Kosta 2012/4/20 Craig Atkinson <[hidden email]>
|
| Powered by Nabble | Edit this page |
