mattwilsn
mattwilsn

Reputation: 188

How to Mock classes that are being instantiated within the test class with EasyMock?

I have a somewhat complicated procedure I am trying to test. getDatesMi makses a call to a method in the same class. That method makes a call to an interface method that returns the result of a query that is cast to a MarketLimits type.

I am using EasyMock and junit.

My questions are:

  1. how can I test getSqlMapClientTemplate().queryForObject ?
  2. how do I mock that the result of getSqlMapClientTemplate().queryForObject is cast to MarketLimits

I am new to java and EasyMock so maybe the answer is obviuos but any help is appreciated.

I am currently getting NullPointerException on subDates.greaterThenOne()

interface for MyServiceDao

import com.foo.bar.domain.MarketLimits;

public interface MyServiceDao {
    public MarketLimits getDates(long orgId) throws DataAccessException;
}

class that implements MyServiceDao

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.foo.bar.domain.MarketLimits;


public class myServiceImpl implements MyServiceDao{

    @Override
    public MarketLimits getDates(long orgId) throws DataAccessException {
        return (MarketLimits) getSqlMapClientTemplate().queryForObject("retrieveLimits", orgId);
    }

}

main class under test

import com.foo.bar.dao.MyServiceDao;

public class myServiceImpl extends reports implements myService {

    @Autowired
    private MyServiceDao myServiceDao;


    public String getDatesMi() throws Exception {
        MarketLimits subDates = getDates(23);

        System.out.print(subDates);  // this prints out null

        if(subDates.greaterThenOne()){
            // do some things
        }

        return "result"
    }


    @Override
    public MarketLimits getDates(long orgId) {
        return myServiceDao.getDates(orgId);
    }


    public setMyServiceDao(MyServiceDao myServiceDao){
        this.myServiceDao = myServiceDao
    }

}

MyTest

@RunWith(EasyMockRunner.class)
public class myServiceImplTest {

    @org.easymock.Mock
    private MyServiceDao myServiceDao;

    @TestSubject
    private MyServiceImpl myServiceImpl = new MyServiceImpl();

    @Test
    public void testGetDatesMi() throws Exception {

        MarketLimits limits = new MarketLimits();
        limits.greaterThenOne(true);
        expect(myServiceDao.getDates()).andReturn(limits);
        replay(myServiceDao);

        myServiceImpl.getDatesMi(12);

    }
}

UPDATE 1

For some reason the EasyMock instance myServiceDao was being created however when a method was called on the EasyMock instance it would return NULL. My solution to this was to create a setter method on myServiceImpl to set my myServiceDao mock. This was a suggestion from Deendayal Garg

UPDATE 2

Turns out I do not need to have a setter =) I changed the title to reflect the real issue I was facing.

Upvotes: 0

Views: 1967

Answers (2)

Henri
Henri

Reputation: 5731

Ok. To give a more complete answer, I tried your code. There are a lot of inconsistencies between the classes. I fixed them the best I could and here is a working example. As you will see, no setter is needed to inject the Dao.

@RunWith(EasyMockRunner.class)
public class MyServiceImplTest {

    @org.easymock.Mock
    private MyServiceDao myServiceDao;

    @TestSubject
    private MyServiceImpl myServiceImpl = new MyServiceImpl();

    @Test
    public void testGetDatesMi() throws Exception {

        MarketLimits limits = new MarketLimits();
        limits.greaterThenOne(true);
        expect(myServiceDao.getDates(23)).andReturn(limits);
        replay(myServiceDao);

        myServiceImpl.getDatesMi();

        verify(myServiceDao);
    }
}

public class MarketLimits {
    private boolean b;

    public void greaterThenOne(boolean b) {
        this.b = b;
    }

    public boolean greaterThenOne() {
        return b;
    }
}

public interface MyServiceDao {
    MarketLimits getDates(long orgId);
}

public class MyServiceImpl {

    private MyServiceDao myServiceDao;


    public String getDatesMi() throws Exception {
        MarketLimits subDates = getDates(23);

        System.out.print(subDates);  // this prints out null

        if(subDates.greaterThenOne()){
            // do some things
        }

        return "result";
    }

    public MarketLimits getDates(long orgId) {
        return myServiceDao.getDates(orgId);
    }

    public void setMyServiceDao(MyServiceDao myServiceDao){
        this.myServiceDao = myServiceDao;
    }

}

Upvotes: 1

Deendayal Garg
Deendayal Garg

Reputation: 5158

Since you are testing MyServiceImpl, you can Completely mock myServiceDao. you need to have a setter for myServiceDao in MyServiceImpl class. This is Mockito spefici but same can be done in EasyMock also.

Inside test class you cna do something like below.

@Test
public void testGetDatesMi() throws Exception {
    myServiceImpl.setMyServiceDao(myServiceDao);// this is mock
    when(myServiceDao.getDates(anyLong()).thenReturn(mockMarketLimits);

   // call you method here

   // verify
}

Upvotes: 0

Related Questions