|
View:
New views
12 Messages
—
Rating Filter:
Alert me
|
|
|
Get hold of parameter to mocked objectWhat is the recommended practice for getting hold of the parameter
passed to a mock object, for further testing. An example of what I want to do: OrderDAO orderDAO = context.mock(OrderDAO.class); checking(new Expectations() { { oneOf(orderDAO).save(with(any(Order.class))); } }); doSomethingThatCreatesAndSavesOrder(); Order order = ...; // The order passed to the mocked OrderDAO.save() // Regular jUnit tests assertEquals("1", order.getCustomer()); assertEquals(3, order.getNoOfLines()); ... I know I can do this using custom matchers: ... oneOf(orderDAO).save(with(allOf( any(Order.class), Matchers.hasProperty("customer", org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local variable for generics to work) ))); ... but if the test fails, the error does not include the specific test that failed but only an "unexpected invocation". The solution that I have come up with would be to create a Matcher that remembers the object it is asked to match, which could then be accessed for further testing. Seems a bit ugly though. My gut tells me somebody should have thought about this already. Is there a better way??? -- </Mattias> --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectMattias,
In my experience, are you sure thats what you want to be testing for? You should only be expecting that the DAO's "save" is being invoked with the order. Anything further would then be getting tested in the implementation's test class i.e. "OrderDAOImplTest", and not in this test. Sorry if I have misunderstood your intentions. Chris > What is the recommended practice for getting hold of the parameter > passed to a mock object, for further testing. > > An example of what I want to do: > > OrderDAO orderDAO = context.mock(OrderDAO.class); > > checking(new Expectations() { > { > oneOf(orderDAO).save(with(any(Order.class))); > } > }); > > doSomethingThatCreatesAndSavesOrder(); > > Order order = ...; // The order passed to the mocked OrderDAO.save() > > // Regular jUnit tests > assertEquals("1", order.getCustomer()); > assertEquals(3, order.getNoOfLines()); > ... > > I know I can do this using custom matchers: > > ... > oneOf(orderDAO).save(with(allOf( > any(Order.class), > Matchers.hasProperty("customer", > org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local > variable for generics to work) > ))); > ... > > but if the test fails, the error does not include the specific test that > failed but only an "unexpected invocation". > > The solution that I have come up with would be to create a Matcher that > remembers the object it is asked to match, which could then be accessed > for further testing. > Seems a bit ugly though. My gut tells me somebody should have thought > about this already. > Is there a better way??? > > -- > > </Mattias> > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectI think that is what I want to do.
To put some more details into my example, I want to test business logic. The output of the business logic is new/updated data, stored via DAOs. There is no return value or anything else to test on. Say for example that I want to verify that OrderCreator.createOrder(1, 2, 3) actually does create an order for customer 1 ordering article no. 2 at a quantity of 3. My plan was to use jMock (since there is a lot of supporting DAO communication going on in the actual business logic), and after calling the method I want the test to examine the resulting Order instance which was passed to the (mocked) OrderDAO by the tested business logic. Is this not the way to go? Do I need to create a dummy implementation of the DAO instead, that does assertions in its save() implementation??? (I agree that the test of the DAO implementation is a totally different matter) </Mattias> chris@... wrote (2009-08-06 14:51): > Mattias, > > In my experience, are you sure thats what you want to be testing for? > > You should only be expecting that the DAO's "save" is being invoked with > the order. > > Anything further would then be getting tested in the implementation's test > class i.e. "OrderDAOImplTest", and not in this test. > > Sorry if I have misunderstood your intentions. > > Chris > > >> What is the recommended practice for getting hold of the parameter >> passed to a mock object, for further testing. >> >> An example of what I want to do: >> >> OrderDAO orderDAO = context.mock(OrderDAO.class); >> >> checking(new Expectations() { >> { >> oneOf(orderDAO).save(with(any(Order.class))); >> } >> }); >> >> doSomethingThatCreatesAndSavesOrder(); >> >> Order order = ...; // The order passed to the mocked OrderDAO.save() >> >> // Regular jUnit tests >> assertEquals("1", order.getCustomer()); >> assertEquals(3, order.getNoOfLines()); >> ... >> >> I know I can do this using custom matchers: >> >> ... >> oneOf(orderDAO).save(with(allOf( >> any(Order.class), >> Matchers.hasProperty("customer", >> org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local >> variable for generics to work) >> ))); >> ... >> >> but if the test fails, the error does not include the specific test that >> failed but only an "unexpected invocation". >> >> The solution that I have come up with would be to create a Matcher that >> remembers the object it is asked to match, which could then be accessed >> for further testing. >> Seems a bit ugly though. My gut tells me somebody should have thought >> about this already. >> Is there a better way??? >> >> -- >> >> </Mattias> >> --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectMattias Jiderhamn wrote:
> What is the recommended practice for getting hold of the parameter > passed to a mock object, for further testing. > > An example of what I want to do: > > OrderDAO orderDAO = context.mock(OrderDAO.class); > > checking(new Expectations() { > { > oneOf(orderDAO).save(with(any(Order.class))); > } > }); > > doSomethingThatCreatesAndSavesOrder(); > > Order order = ...; // The order passed to the mocked OrderDAO.save() > > // Regular jUnit tests > assertEquals("1", order.getCustomer()); > assertEquals(3, order.getNoOfLines()); > ... > > I know I can do this using custom matchers: > > ... > oneOf(orderDAO).save(with(allOf( > any(Order.class), > Matchers.hasProperty("customer", > org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local > variable for generics to work) > ))); > ... > > but if the test fails, the error does not include the specific test that > failed but only an "unexpected invocation". > > The solution that I have come up with would be to create a Matcher that > remembers the object it is asked to match, which could then be accessed > for further testing. > Seems a bit ugly though. My gut tells me somebody should have thought > about this already. > Is there a better way??? > http://thread.gmane.org/gmane.comp.java.jmock.user/2278/focus=2284 for my class that does this. --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectMattias,
I think I understand what you mean. This is just my opinion, but from my personal learning experience, if a piece of behaviour is not easily testable, it probably means the code needs to be refactored. This is what TDD excels at forcing you to. refactoring possible poor design. To me, because this is not easily testable it highlights that your business logic should not be interested in checking that the values of domain objects are correct. Your method should probably just be: OrderCreator.createOrder(order); and then assert that the order creates calls save on the DAO. Setting the values of your domain object POJO (order) should probably be done in a much higher level such as a Struts action, or Servlet. And when you test your DAO you can test 1. That all the values nessessary in the domain object have been set to legal/acceptable values. or 2. That exceptions from your persistance framework are correctly handled if a POJO is passed with illegal values. Thats the kinda way we do it in here. Chris > I think that is what I want to do. > > To put some more details into my example, I want to test business logic. > The output of the business logic is new/updated data, stored via DAOs. > There is no return value or anything else to test on. > Say for example that I want to verify that OrderCreator.createOrder(1, > 2, 3) actually does create an order for customer 1 ordering article no. > 2 at a quantity of 3. > My plan was to use jMock (since there is a lot of supporting DAO > communication going on in the actual business logic), and after calling > the method I want the test to examine the resulting Order instance which > was passed to the (mocked) OrderDAO by the tested business logic. > > Is this not the way to go? > Do I need to create a dummy implementation of the DAO instead, that does > assertions in its save() implementation??? > > (I agree that the test of the DAO implementation is a totally different > matter) > > </Mattias> > > > chris@... wrote (2009-08-06 14:51): >> Mattias, >> >> In my experience, are you sure thats what you want to be testing for? >> >> You should only be expecting that the DAO's "save" is being invoked with >> the order. >> >> Anything further would then be getting tested in the implementation's >> test >> class i.e. "OrderDAOImplTest", and not in this test. >> >> Sorry if I have misunderstood your intentions. >> >> Chris >> >> >>> What is the recommended practice for getting hold of the parameter >>> passed to a mock object, for further testing. >>> >>> An example of what I want to do: >>> >>> OrderDAO orderDAO = context.mock(OrderDAO.class); >>> >>> checking(new Expectations() { >>> { >>> oneOf(orderDAO).save(with(any(Order.class))); >>> } >>> }); >>> >>> doSomethingThatCreatesAndSavesOrder(); >>> >>> Order order = ...; // The order passed to the mocked OrderDAO.save() >>> >>> // Regular jUnit tests >>> assertEquals("1", order.getCustomer()); >>> assertEquals(3, order.getNoOfLines()); >>> ... >>> >>> I know I can do this using custom matchers: >>> >>> ... >>> oneOf(orderDAO).save(with(allOf( >>> any(Order.class), >>> Matchers.hasProperty("customer", >>> org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local >>> variable for generics to work) >>> ))); >>> ... >>> >>> but if the test fails, the error does not include the specific test >>> that >>> failed but only an "unexpected invocation". >>> >>> The solution that I have come up with would be to create a Matcher that >>> remembers the object it is asked to match, which could then be accessed >>> for further testing. >>> Seems a bit ugly though. My gut tells me somebody should have thought >>> about this already. >>> Is there a better way??? >>> >>> -- >>> >>> </Mattias> >>> > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectOn 6 Aug 2009, at 14:20, Julian Hall wrote:
> Mattias Jiderhamn wrote: >> The solution that I have come up with would be to create a Matcher >> that >> remembers the object it is asked to match, which could then be >> accessed >> for further testing. >> Seems a bit ugly though. My gut tells me somebody should have thought >> about this already. >> Is there a better way??? >> > I think doing it via an action is cleaner. See http://thread.gmane.org/gmane.comp.java.jmock.user/2278/focus=2284 > for my class that does this. If you want to stash a parameter, then an Action is the place to do it--but it's almost certainly the wrong thing to do. S Steve Freeman Winner of the Agile Alliance Gordon Pask award 2006 http://www.m3p.co.uk M3P Limited. Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ. Company registered in England & Wales. Number 03689627 --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectAre you working with the most recent version of jMock?
There's new functionality to show where an expectation mismatched, not just that it failed. You can extend a FeatureMatcher to extract individual details from the object being matched (look in the code for examples). Hanging on to a parameter for checking goes against the grain of jMock's approach. If you must, then use an Action, but you probably shouldn't. S. On 6 Aug 2009, at 13:37, Mattias Jiderhamn wrote: > oneOf(orderDAO).save(with(allOf( > any(Order.class), > Matchers.hasProperty("customer", > org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as > local > variable for generics to work) > ))); > ... > > but if the test fails, the error does not include the specific test > that > failed but only an "unexpected invocation". > > The solution that I have come up with would be to create a Matcher > that > remembers the object it is asked to match, which could then be > accessed > for further testing. > Seems a bit ugly though. My gut tells me somebody should have thought > about this already. > Is there a better way??? Steve Freeman Winner of the Agile Alliance Gordon Pask award 2006 http://www.m3p.co.uk M3P Limited. Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ. Company registered in England & Wales. Number 03689627 --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectApologies for the late arrival to this thread. I (think that I) have a similar requirement to the OP. My DAO (using iBatis) is expected to call a routine on a sqlMapClient object (mocked) when triggered to do so. It passes two arguments. The first is a simple string. The second is a Map<String, Object>. I need to check that the Map that is passed in contains two other objects that were originally supplied to the DAO under test. e.g. instance.triggerEvent( object1, object2); should give me an expectation as follows one(sqlmc).hitRoutine(with(equals("abc")), with(a(Map.class))); and the Map passed as the second argument *should* contain object1 under the key "object1" and object2 under the key "object2" Is this extended FeatureMatcher referred to above the only way to test that the DAO is constructing the second argument correctly? Later, Andy |
|
|
Re: Get hold of parameter to mocked objectOn 11 Sep 2009, at 11:25, Andy Law wrote:
> Apologies for the late arrival to this thread. > > I (think that I) have a similar requirement to the OP.e.g. > > instance.triggerEvent( object1, object2); > > should give me an expectation as follows > > one(sqlmc).hitRoutine(with(equals("abc")), with(a(Map.class))); > > and the Map passed as the second argument *should* contain object1 > under the > key "object1" and object2 under the key "object2" you can try: one(sqlmc).hitRouting(with(equalTo("abc")), with(allOf(hasEntry("object1", object1), hasEntry("object2", object2)))); S. Steve Freeman Winner of the Agile Alliance Gordon Pask award 2006 http://www.m3p.co.uk M3P Limited. Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ. Company registered in England & Wales. Number 03689627 --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectThanks for that suggestion Steve. In fact, since I posted I wrote a new Matcher that does the job nicely. I coded it as 'aMapThatMatches()' which makes the test code nicely readable one.(sqlmc).hitRoutine(with(equalTo("abc")), with(aMapThatMatches(templateMap))); I'm happy to share/contribute this with others. Does it hold any interest for the JMock/Hamcrest devs? Later, Andy |
|
|
Re: Get hold of parameter to mocked object> Thanks for that suggestion Steve.
> > In fact, since I posted I wrote a new Matcher that does the job > nicely. I > coded it as 'aMapThatMatches()' which makes the test code nicely > readable > > one.(sqlmc).hitRoutine(with(equalTo("abc")), > with(aMapThatMatches(templateMap))); > > I'm happy to share/contribute this with others. Does it hold any > interest > for the JMock/Hamcrest devs? > > Later, to clarify. aMapThatMatches(templateMap) checks that the actual map has the same entries as the templateMap, or does it do something else? S. --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Get hold of parameter to mocked objectYou supply a template Map that has the key/value pairs that are expected. The Matcher checks that the argument/actual Map contains each of those key/value pairs. The argument may contain other entries too in the current incarnation. If/when I reach a point that I need an *exact* comparison then I'll add that in somewhere (aMapThatExactlyMatches()??) So, if template === ( "a" => "a string", "user" = USEROBJECT) then an argument that looks like ( "a" => "a string", "user" = USEROBJECT, "somethingelse" => 42) will pass. Later, Andy |
| Free embeddable forum powered by Nabble | Forum Help |