Announcement Announcement Module
Collapse
No announcement yet.
Integration Testing with Spring and Mocks Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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, 08:55 AM.

  • #2
    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?

    Comment


    • #3
      Or use Mockito which works both with interfaces and classes.

      regards
      Grzegorz Grzybek

      Comment


      • #4
        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.

        Comment


        • #5
          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

          Comment


          • #6
            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...?

            Comment

            Working...
            X