Kent Larsson | 2 Jun 11:07 2008
Picon

Is it possible to get the setter getter relationship to work using a mock object?

Hi,

I have a class which I create a mock object of (using class
imposterizer) in our tests, let's call the class SomeEntity. Then I
have another class which I'm testing, it adds an instance of
SomeEntity to a collection, while at the same time giving the instance
a unique identity using the setId(int id) method of SomeEntity. On the
calls after setId I would like to return the value which our
SomeEntity instance was given. Is it possible and how should I go
about doing it?

Best regards,
Kent Larsson

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Steve Freeman | 2 Jun 11:41 2008
Picon

Re: Is it possible to get the setter getter relationship to work using a mock object?

1) Entity? Hmmm. Is this really just a data object? Does it have any  
interesting behaviour involving collaborators? If it is just a data  
object, maybe it would be better to use the real thing?

2) What are the uses of this id visible in the tests, could their  
constraints be loosened so that you don't care what its value is?

3) Why is the id not a predictable value in a unit test?

4) If you really have to, you could create a custom action to hold on  
to the given id, but this is probably a bad idea.

S.

On 2 Jun 2008, at 10:07, Kent Larsson wrote:
> Hi,
>
> I have a class which I create a mock object of (using class
> imposterizer) in our tests, let's call the class SomeEntity. Then I
> have another class which I'm testing, it adds an instance of
> SomeEntity to a collection, while at the same time giving the instance
> a unique identity using the setId(int id) method of SomeEntity. On the
> calls after setId I would like to return the value which our
> SomeEntity instance was given. Is it possible and how should I go
> about doing it?
>
> Best regards,
> Kent Larsson
>
> ---------------------------------------------------------------------
(Continue reading)

Kent Larsson | 2 Jun 12:13 2008
Picon

Re: Is it possible to get the setter getter relationship to work using a mock object?

> 1) Entity? Hmmm. Is this really just a data object? Does it have any
> interesting behaviour involving collaborators? If it is just a data object,
> maybe it would be better to use the real thing?
>
> 2) What are the uses of this id visible in the tests, could their
> constraints be loosened so that you don't care what its value is?
>
> 3) Why is the id not a predictable value in a unit test?
>
> 4) If you really have to, you could create a custom action to hold on to the
> given id, but this is probably a bad idea.

Thank you for your answer! I really need some help as I'm a novice
mocker and a beginner unit tester. :-)

The short answer:

The id instance variable is used for checknig if two entity instances
are equal. The id's are given from a simulated integration layer,
which gives the id's in sequential order. But it feels a bit dirty to
write the test to depend on the simulated integration layers way of
giving out ids.

The all too long answer: (Sorry, I didn't know how to compress it more
without loosing relevant information)

It's more or  less a data carrier (it's an JPA entity and we have
chosen to have as much logic as possible in the manager EJB classes).
We have a manager class which is responsible for a tree structure of
Library enteties, where each Library may hold n number of UserGroup's.
(Continue reading)

Steve Freeman | 2 Jun 12:55 2008
Picon

Re: Is it possible to get the setter getter relationship to work using a mock object?

On 2 Jun 2008, at 11:13, Kent Larsson wrote:
> The short answer:
>
> The id instance variable is used for checknig if two entity instances
> are equal. The id's are given from a simulated integration layer,
> which gives the id's in sequential order. But it feels a bit dirty to
> write the test to depend on the simulated integration layers way of
> giving out ids.

if you have a simulation, I would have thought it would be easy to  
seed the ID generation.

> It's more or  less a data carrier (it's an JPA entity and we have
> chosen to have as much logic as possible in the manager EJB classes).
> We have a manager class which is responsible for a tree structure of
> Library enteties, where each Library may hold n number of UserGroup's.
>
> At the moment the business logic to update the Library tree is
> complete. This means adding/updating/removing Library instances and
> the UserGroup's they contain.
>
> We want to check that this logic functions according to our business
> rules. That means that the manager class does what we expect it to do.
> To not make our tests too brittle mocking Library and UserGroup seemed
> like a good idea. These are concrete classes but ClassImposteriser
> made this less of a problem.

Personally, I view class mocking as a problem, but that's just me :)

> Ideally mocking these two concrete classes would be nice. As the tests
(Continue reading)

Erick Dovale | 2 Jun 15:56 2008
Picon

Re: Strange issue with aNonNull expectation

You should say with(aNonNull(Tag.class)).

It seems like you are missing the with when setting up the expectation.

On Thu, May 8, 2008 at 3:56 PM, Steve Freeman <steve-/6t1Ty3A97Vaa/9Udqfwiw@public.gmane.org> wrote:
I wonder if it's trying to match the method with a signature of a Tag argument and so is missing the signature with an Object argument? Try aNonNull(Object.class) and see if that works. Do you have template type checking turned off in the test method or class? You could also try the hamcrest matcher notNullValue().


S.


On 8 May 2008, at 17:32, Thomas Becker wrote:

I know that this calls will happen exactly once. Isn't the one() clause the correct one to use in my case? Why do you think allowing fits better in my scenario? Don't get me wrong, I just do not understand why allowing should be more expressive here. I'm happy for all suggestions and implement them if I understand them.

I modified the expectation to explicitly return null as you suggested, since it's more expressive:
         one (tagDao).findTagByKeyForClientId(tagKey, clientId);
         will(returnValue(null));

TagDao is an interface and the save() method is implemented with once with only one signature: save(Object object).

Strange thing however is, that I'm doing a similar thing in another test now, which just works fine. The only difference is that I'm using saveOrUpdate now instead of save. So I tried to refactor the service layer code to use saveOrUpdate in the other case as well. But it didn't solve the assertion exception so I rolled the change back.

Here's where it works fine:

  <at> Test
 public void testUpdateTag() throws TagNotFoundException{
           // expectations
     context.checking(new Expectations() {{
         one (tagDao).findTagById(tagId);
          will(returnValue(tag));
         one(tagDao).saveOrUpdate(with(aNonNull(Tag.class)));
     }});
           // method to test
     Tag tag = tagService.updateTag(tagId, "newKey", "newDescription", contractId);
     assertEquals("returned Tag should have newKey as tagKey", "newKey", tag.getKey());
     assertEquals("returned Tag should have newDescription as tagDescription", "newDescription", tag.getDescription());
 }

Steve Freeman wrote:
As a first cut, I'd suggest adding the return clause -- although that shouldn't make a difference. (incidentally, I'd also suggest using the allowing() clause for the query methods, it's the same implementation but we think it's more expressive about the intentions of the test).

Sorry, when I said Tag I meant TagDao.

S.

On 8 May 2008, at 10:04, Thomas Becker wrote:
Hey Steve,

thanks for the fast reply.

this one: one (tagDao).findTagByKeyForClientId(tagKey, clientId);  is a check if a Tag with tagKey does already exist and the expected result is null. That's why I do not have a will clause for that one. Maybe will(returnValue(null) would be a cleaner and more readable solution. I will change that, so it's clear for everyone.

Tag is a model class pojo. Actually this class follows the anaemic antipattern and does only work as a data container with getters/setters. Does aNonNull only work with interfaces?!

Cheers,
Thomas

Steve Freeman wrote:
I'm confused too.

The only thing I notice is that you seem to have some defaults set up on the tagDao, since the find method doesn't have a will() clause. Is that just a typo or is there more setup going on? Also, is Tag an interface or class and are there any overloaded methods?

S.

On 8 May 2008, at 08:25, Thomas Becker wrote:
Hi Usergroup,

I'm using jmock more and more extensively in my Unit Test and I really like it. Saves myself a bunch of work. However I got a strange AssertionError which I do neither really understand nor do I get it resolved.  Maybe you can shed some light on me.

Here's the test method:

/**
 * Test method for { <at> link net.netm.me.moritz.service.impl.TagServiceImpl#addTag(java.lang.String, java.lang.String, int, Long)}.
 */
<at> Test
public void testAddGenreTag() throws TagAlreadyExistsException{
         // expectations
   context.checking(new Expectations() {{
        one (contractDao).findContract(contractId);
        will(returnValue(contract));
       one (tagDao).findTagByKeyForClientId(tagKey, clientId);
        one (tagTypeService).getTagType(genreTagType.getId());
        will (returnValue(genreTagType));
        one (tagDao).save(aNonNull(Tag.class));
   }});
         // method to test
   Tag newTag = tagService.addTag(tagKey, tagDescription, genreTagType.getId(), contractId);
   assertTrue("new Genre Tag should start  with Genre", newTag.getKey().startsWith("GENRE."));
}

This is the expectation which fails:
one (tagDao).save(aNonNull(Tag.class));

And the FailureTrace:

java.lang.AssertionError: unexpected invocation: tagDao.save(<Tag[id=0,key=GENRE.Take That,client.id=186,description=Tag for Artist Take That,tagType.key=GENRE]>)
expectations:
expected exactly 1 time, already invoked 1 time: contractDao.findContract(<21009747L>); returns <net.netm.me.core.model.Contract <at> 15664f1a[id=21009747,name=<null>]>
expected exactly 1 time, already invoked 1 time: tagDao.findTagByKeyForClientId("Take That", <186L>); returns a default value
expected exactly 1 time, already invoked 1 time: tagTypeService.getTagType(<0>); returns <TagType[id=0,key=GENRE]>
expected exactly 1 time, never invoked: tagDao.save(<not null>); returns a default value
at org.jmock.internal.InvocationDispatcher.dispatch(InvocationDispatcher.java:56)
at org.jmock.Mockery.dispatch(Mockery.java:204)
at org.jmock.Mockery.access$000(Mockery.java:37)
at org.jmock.Mockery$MockObject.invoke(Mockery.java:246)
at org.jmock.internal.InvocationDiverter.invoke(InvocationDiverter.java:27)
at org.jmock.internal.ProxiedObjectIdentity.invoke(ProxiedObjectIdentity.java:36)
at org.jmock.lib.JavaReflectionImposteriser$1.invoke(JavaReflectionImposteriser.java:33)
at $Proxy7.save(Unknown Source)
at net.netm.me.moritz.service.impl.TagServiceImpl.createAndPersistTag(TagServiceImpl.java:257)
at net.netm.me.moritz.service.impl.TagServiceImpl.addTag(TagServiceImpl.java:128)
at net.netm.me.moritz.service.TagServiceTest.testAddGenreTag(TagServiceTest.java:262)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.jmock.integration.junit4.JMock$1.invoke(JMock.java:36)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

I excpect any Tag.class and tagDao.save gets called with a Tag.class  parameter. So the test shouldn't fail at all?! But it does....any clue why? Am I getting the aNonNull functionality wrong? It's the first time I'm using it.

Thanks a lot for any help.

Cheers,
Thomas


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email



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



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

 http://xircles.codehaus.org/manage_email



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



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

 http://xircles.codehaus.org/manage_email



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



Steve Freeman | 2 Jun 16:05 2008
Picon

Re: Strange issue with aNonNull expectation

doh.

Yes, it's a real usability trap.

S.

On 2 Jun 2008, at 14:56, Erick Dovale wrote:

> You should say with(aNonNull(Tag.class)).
>
> It seems like you are missing the with when setting up the  
> expectation.
>
> On Thu, May 8, 2008 at 3:56 PM, Steve Freeman <steve@...> wrote:
>
>> I wonder if it's trying to match the method with a signature of a Tag
>> argument and so is missing the signature with an Object argument? Try
>> aNonNull(Object.class) and see if that works. Do you have template  
>> type
>> checking turned off in the test method or class? You could also try  
>> the
>> hamcrest matcher notNullValue().

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

Jeroen Verhagen | 4 Jun 11:27 2008
Picon

custom Matcher necessary?

Hi all,

I'm using jMock 2.4.0 to junit test my code.

In the following test example:

  one(message).setContent(with(aNonNull(StringBuffer.class)));

Is it somehow possible to capture and inspect the value that is passed
to the method setContent()? Or do I have to write a custom Matcher to
do that?

--

-- 

regards,

Jeroen

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Steve Freeman | 4 Jun 11:44 2008
Picon

Re: custom Matcher necessary?

First, why do you want to do that?

Second, if you want to capture an argument, use an action not a matcher.

S.

On 4 Jun 2008, at 10:27, Jeroen Verhagen wrote:
> Hi all,
>
> I'm using jMock 2.4.0 to junit test my code.
>
> In the following test example:
>
>  one(message).setContent(with(aNonNull(StringBuffer.class)));
>
> Is it somehow possible to capture and inspect the value that is passed
> to the method setContent()? Or do I have to write a custom Matcher to
> do that?

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

Jan Kodet | 4 Jun 13:04 2008
Picon

aNonNull unexpected behaviour


I've probably misinterpreted something, but here goes....

Using the State pattern (see e.g.
http://exciton.cs.rice.edu/JavaResources/DesignPatterns/StatePat.htm) I want
to test the logic in my states. So I have two interfaces: State and Context.
Interface Context defines the method setState(State newState) and interface
State defines some event handling methods. The interfaces are then
implemented by the classes I want to test.

My test methods look something like (using version 2.4.0):

     <at> Test
    public void testOnEvent() {
        // Class under test
        StateOne stateOne = new StateOne(mockContext);

        context.checking(new Expectations() {
                {
                    // We should transit to StateTwo

one(mockContext).setState(with(aNonNull(StateTwo.class)));
                }
        });

        stateOne.onEvent(new SomeEvent());
        context.assertIsSatisfied();
    }

To my delight, the test succeeds. My joy was somewhat dimmed when I noted
that I can put any state I like as argument to aNonNull(), as long as it
implements State. They all fullfill the expectation. 

This was not what I'd expect. I hoped that "with(aNonNull(StateTwo.class))"
would ensure that I go to the right state, not just that the argument has
the correct interface. 

I assume that I've got something wrong, but hope for any pointers to how I
should do my tests to ensure that I really go to StateTwo.

Cheers,

/JMK
--

-- 
View this message in context: http://www.nabble.com/aNonNull-unexpected-behaviour-tp17644154p17644154.html
Sent from the jMock - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Jeroen Verhagen | 4 Jun 13:34 2008
Picon

Re: custom Matcher necessary?

Hi Steve,

On Wed, Jun 4, 2008 at 11:44 AM, Steve Freeman <steve@...> wrote:
> First, why do you want to do that?

I want to check the content and assert that it meets my expectations.

> Second, if you want to capture an argument, use an action not a matcher.

Thanks, I will look into actions. I hadn't considered them, but then
I'm new to testing using jMock.

--

-- 

regards,

Jeroen

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Gmane