使用Mockito模拟Hibernate的SessionFactory时测试失败

时间:2015-07-08 06:07:48

标签: java unit-testing java-ee junit mockito

好的,所以继承代码

使用MockitoJUnitRunner运行测试,并在@Before方法中执行

MockitoAnnotations.initMocks(this);

@Test
public void verifyTimestampTest(){
    TargetHistoryPK tHistoryPK = Mockito.mock(TargetHistoryPK.class);

    targetHistoryDAO = Mockito.mock(TargetHistoryDAOimpl.class);        
    session = Mockito.mock(Session.class);
    sessionFactory = Mockito.mock(SessionFactory.class);

    Mockito.when(sessionFactory.getCurrentSession()).thenReturn(session);

    TargetHistory th = Mockito.mock(TargetHistory.class);
    Mockito.when(session.save(th)).thenReturn(tHistoryPK);

    boolean h = targetHistoryDAO.addTargetHistory(th);

    System.out.println("erh: "+ th.getTarget_update() + h);
    assertNotNull("Timestamp is null", th.getTarget_update());
}

和测试方法

public class TargetHistoryDAOimpl implements TargetHistoryDAO {


    @Autowired
    private SessionFactory sessionFactory;

    public TargetHistoryDAOimpl() {     
    }

    public TargetHistoryDAOimpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    @Override
    public boolean addTargetHistory(TargetHistory th) {

        if(th.getTarget_update() == null){
            Date now = new Date();
            Timestamp timestamp = new Timestamp(now.getTime());
            th.setTarget_update(timestamp);
        }
        Session session = sessionFactory.getCurrentSession();
        TargetHistoryPK pk = (TargetHistoryPK)session.save(th);
        if(pk != null)
            return true;

        return false;
    }

}

通常从下面提供的服务类方法调用addTargetHistory()

    @Transactional
    public boolean registerTargetActivity(TargetHistory th) {
        // TODO Auto-generated method stub
        return targetHistoryDao.addTargetHistory(th);
    }

有人可以向我解释为什么我的测试verifyTimestampTest()会失败吗?

编辑我在测试中添加了一行(我无法调试 - 尝试调试时出现sts错误)

if(th == null)
        System.out.println("rggrgr");
像这样

@Test
public void verifyTimestampTest(){
    TargetHistoryPK tHistoryPK = Mockito.mock(TargetHistoryPK.class);
    targetHistoryDAO = Mockito.mock(TargetHistoryDAOimpl.class);        
    session = Mockito.mock(Session.class);
    sessionFactory = Mockito.mock(SessionFactory.class);

    Mockito.when(sessionFactory.getCurrentSession()).thenReturn(session);

    TargetHistory th = new TargetHistory();
    Mockito.when(session.save(th)).thenReturn(tHistoryPK);

    boolean h = targetHistoryDAO.addTargetHistory(th);

    if(th == null)
        System.out.println("targetHistory is null!");

    System.out.println("erh: "+ th.getTarget_update() + h);
    assertNotNull("Timestamp is null", th.getTarget_update());


}

我得到了警告"死代码"。为什么????为什么死代码?

2 个答案:

答案 0 :(得分:1)

这是因为您的 TargetHistory 是模拟。您不会为该模拟方法设置任何行为。这就是为什么他们什么也不做并返回null。在this Mockito documentation page,它说:

  

默认情况下,对于返回值的所有方法,mock返回null,空集合或适当的原始/原始包装值(例如:0,false,...表示int / Integer,boolean / Boolean,...)

     

请注意默认情况下模拟上的void方法不执行任何操作!

您需要将TargetHistory模拟替换为真实对象或存根。

答案 1 :(得分:0)

好的,所以我发现问题出在

targetHistoryDAO = Mockito.mock(TargetHistoryDAOimpl.class);

我显然没有正确理解模拟是什么。 Mockito从未真正致电

targetHistoryDAO.addTargetHistory(th);

我需要添加一行

Mockito.when(targetHistoryDAO.addTargetHistory(th)).thenCallRealMethod();

在调用此方法之前。所以最终的代码看起来像这样

    TargetHistoryPK tHistoryPK = Mockito.mock(TargetHistoryPK.class);
    targetHistoryDAO = Mockito.mock(TargetHistoryDAOimpl.class);        
    session = Mockito.mock(Session.class);
    sessionFactory = Mockito.mock(SessionFactory.class);

    Mockito.when(sessionFactory.getCurrentSession()).thenReturn(session);

    TargetHistory th = new TargetHistory();
    Mockito.when(session.save(th)).thenReturn(tHistoryPK);
    Mockito.when(targetHistoryDAO.addTargetHistory(th)).thenCallRealMethod();
    boolean h = targetHistoryDAO.addTargetHistory(th);
    assertNotNull("Timestamp is null", th.getTarget_update());