如何使用EasyMock模拟在测试类中实例化的类?

时间:2016-04-21 15:26:36

标签: java spring unit-testing junit easymock

我试图测试一个有点复杂的程序。 getDatesMi调用同一个类中的方法。那个方法打个电话 一个接口方法,它返回一个转换为MarketLimits类型的查询结果。

我正在使用EasyMock和junit。

我的问题是:

  1. 如何测试getSqlMapClientTemplate()。queryForObject?
  2. 如何模拟getSqlMapClientTemplate()。queryForObject的结果被强制转换为MarketLimits
  3. 我是java和EasyMock的新手,所以答案可能是显而易见的,但感谢任何帮助。

    我目前在subDates.greaterThenOne()上获得NullPointerException

    MyServiceDao的界面

    import com.foo.bar.domain.MarketLimits;
    
    public interface MyServiceDao {
        public MarketLimits getDates(long orgId) throws DataAccessException;
    }
    

    实现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);
        }
    

    }

    正在测试的主要课程

    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);
    
        }
    }
    

    更新1

    由于某种原因,正在创建EasyMock实例myServiceDao,但是当在EasyMock实例上调用方法时,它将返回NULL。我的解决方案是在myServiceImpl上创建一个setter方法来设置myServiceDao mock。这是Deendayal Garg

    的建议

    更新2

    原来我不需要有一个setter =) 我更改了标题以反映我面临的真正问题。

2 个答案:

答案 0 :(得分:1)

确定。为了给出更完整的答案,我尝试了你的代码。这些类之间存在很多不一致之处。我尽力修好他们,这是一个有效的例子。正如您将看到的,注入Dao不需要setter。

@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;
    }

}

答案 1 :(得分:0)

由于您正在测试MyServiceImpl,因此您可以完全模拟myServiceDao。您需要在myServiceDao课程中设置MyServiceImpl的设定器。这是Mockito spefici,但同样可以在EasyMock中完成。

在测试课程内,您可以执行以下操作。

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

   // call you method here

   // verify
}