Results 1 to 6 of 6

Thread: Integration Testing with Spring and Mocks

  1. #1
    Join Date
    Dec 2009
    Posts
    20

    Default Integration Testing with Spring and Mocks

    I know this post doesnt have much to do with the Spring framework but wanted to get some feedback from fellow developers as this must be a common problem.

    Furthermore I using Spring for integration testing purposes where Im testing business methods expose by a service layer. More so the problem I have is that part of the integration testing is to create/mock domain models/objects used by the services ie.:

    Code:
    	Client client = EasyMock.createNiceMock(Client.class);
    	EasyMock.expect(client.getPrimaryId()).andReturn("simpsonb");
    	EasyMock.replay(client);
    
    	Collection<Address> data = getServiceLocator().getAddressService().findAddressesByClient(client);
    	assertNotNull(data);
    	assertEquals(3, data.size());
    
    	EasyMock.verify(client);
    Two problems im facing:
    1. If I use EasyMock as above ALL my domain models that I want to mock have to be interfaces of which currently no domain models are as to me this is an extreme case of too many interfaces especially as all my models are hibernate specific. Find below an outline of the Client model:

    Code:
    @Entity
    @Table(name = &quot;Client&quot;)
    public class Client extends BaseLookupModel&lt;String&gt; {
    
    	@Id
    	@GeneratedValue(generator = &quot;ClientIDGenerator&quot;)
    	@GenericGenerator(name = &quot;ClientIDGenerator&quot;, strategy = ClientIDGenerator.STRATEGY)
    	@Column(name = &quot;ClientCode&quot;)
    	@Audited
    	private String primaryId;
    
    	@Column(name = &quot;GroupCode&quot;)
    	@Audited
    	private String group;
    
    	@Column(name = &quot;TitleCode&quot;)
    	private String title;
    
    	@Column(name = &quot;Initials&quot;)
    	private String initials;
    ...
    }
    2. Im trying to replicate an invocation to the "getPrimaryId()" method of which is causing an issue when I mock the Client.class using either Mockito and EasyMock as the getPrimaryId() method is used in the "equals()" method in the domain model. This is causing a StackOverflow as both mocking frameworks use the equals method to determine which mock object to evaluation and test against. The equals method is as follow:

    Code:
    	@Override
    	public final boolean equals(Object obj) {
    		if(!(obj instanceof BaseModel&lt;?&gt;)) {
    			return false;
    		}
    
    		BaseModel&lt;?&gt; baseEntity = (BaseModel&lt;?&gt;)obj;
    		if(baseEntity.getPrimaryId() != null && getPrimaryId() != null) {
    			return baseEntity.getPrimaryId().equals(this.getPrimaryId());
    		} else {
    			return super.equals(obj);
    		}
    	}
    Any feedback will be awesome, thanks.
    Last edited by jjrun1; Apr 1st, 2010 at 07:55 AM.

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    If I use EasyMock as above ALL my domain models that I want to mock have to be interfaces of which currently no domain models are as to me this is an extreme case of too many interfaces especially as all my models are hibernate specific.
    Unless I'm missing something why can't you use the EasyMock Class Extension?
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

  3. #3
    Join Date
    Oct 2008
    Location
    Poland, Wrocław
    Posts
    424

    Default

    Or use Mockito which works both with interfaces and classes.

    regards
    Grzegorz Grzybek

  4. #4
    Join Date
    Dec 2009
    Posts
    20

    Default

    This problem happens if I use either Mockito or EasyMock extension.

    If I use EasyMock as above ALL my domain models that I want to mock have to be interfaces of which currently no domain models are as to me this is an extreme case of too many interfaces especially as all my models are hibernate specific.
    All I ways saying here, is that if I just use EasyMock then I have to use Interfacess.

    The problem im facing is that method that I am mocking is used in the "equals()" method as this is causing a StackOverflow.

  5. #5
    Join Date
    Oct 2008
    Location
    Poland, Wrocław
    Posts
    424

    Default

    I'm not quite aware if Mockito/EasyMock implementation details but I think the equals() (and hashcode()) methods are handled specially by particular mock's InvocationHandler...

    If your equals() contains some logic that need to be tested than maybe you shoudl extract it to some special method.

    But if you want to test equals() for the sake of code coverage - don't do it

    regards
    Grzegorz Grzybek

  6. #6
    Join Date
    Dec 2009
    Posts
    20

    Default

    Well both Mockito and EasyMock add all mock objects to a collection, specially an ArrayList. When the mocks are added the "equals" method is invoked. Now as you can see from my original post, I override the equals method to evaluate using the primary key value as what is the best way to test equality for database objects... obviously to use the primary key:

    Code:
    	@Override
    	public final boolean equals(Object obj) {
    		if(!(obj instanceof BaseModel)) {
    			return false;
    		}
    
    		BaseModel baseEntity = (BaseModel)obj;
    		if(baseEntity.getPrimaryId() != null && getPrimaryId() != null) {
    			return baseEntity.getPrimaryId().equals(this.getPrimaryId());
    		} else {
    			return super.equals(obj);
    		}
    	}
    So I cant simply extract it to "some special" method as suggested. More so Im not trying to test the "equals" method, im testing the invocation of the "getPrimaryId" method:

    Code:
    EasyMock.expect(client.getPrimaryId()).andReturn("simpsonb");
    Of which both testing frameworks indirectly invoke "equals" of which so happens to be that my implementation makes use of the method im trying to test. Reading a few posts on other forums this seems to be a known issue, now I was curious if anyone has found a work around for this?!

    With that said I cant believe that not more people have experienced this problem as most developers would override the equals method for database objects to use the primaryId attribute to determine object equality...?

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •