java - 在java测试中没有收到错误

标签 java testing junit mocking mockito

我的测试不应该通过。我应该在第 2 行收到错误,因为我在第 1 行输入了错误的值 new Long(0)。 请告诉我我的错误在哪里。 谢谢。

    @Test
    public void getPersonListByOtdelIdTest() {            
        Long otdelId = new Long(454);
        ArgumentCaptor<Long> argumentOtdelId = ArgumentCaptor.forClass(Long.class);
        SessionFactory mockedSessionFactory = mock(SessionFactory.class);
        Session session = mock(Session.class);
        Query query = mock(Query.class);
        PersonDAOImpl personDAO = new PersonDAOImpl(mockedSessionFactory);
        when(mockedSessionFactory.getCurrentSession()). thenReturn(session);
        when(session.createQuery("FROM Person P where P.otdel.otdelId = :otdelId")).thenReturn(query);
 #1-->  when(query.setParameter("otdelId", new Long(0))).thenReturn(query);
        when(query.list()).thenReturn(persons);

        List<Person> expectedPersons =  personDAO.getPersonListByOtdelId(otdelId);

        verify(mockedSessionFactory).getCurrentSession();
        verify(session).createQuery("FROM Person P where P.otdel.otdelId = :otdelId");
        verify(query).setParameter(eq("otdelId"), argumentOtdelId.capture());
        verify(query).list();
 #2-->  assertEquals(otdelId, argumentOtdelId.getValue());
        assertTrue(expectedPersons.containsAll(persons));
    }

 public class PersonDAOImpl implements PersonDAO {
    public List<Person> getPersonListByOtdelId(Long otdelId) {
        Query query = sessionFactory.getCurrentSession().createQuery("FROM Person P where P.otdel.otdelId = :otdelId");
        query.setParameter("otdelId", otdelId);
        List<Person> listPersons = query.list();
        return listPersons;
    } 
 }

最佳答案

我不明白为什么您会期望 #2 断言失败。您的测试将 454(作为 Long)传递给 getPersonListByOtdelId(),因此将传递给 query.setParameter() 。 #1 中的 when() 代码本质上是空操作,因为没有使用这些值调用 query.setParameter(),但 Mockito 不会提示如果 when() 中指定的调用从未发生,并且被测代码不检查返回值,则没有异常。

无论如何,您都不需要ArgumentCaptor;您只需要让 Mockito 验证是否将正确的值传递给 setParameter()

事实上,许多验证调用是不需要的,您可以这样做:

@Test
public void getPersonListByOtdelIdTest() {
  Long otdelId = 454L; // or = Long.valueOf(454); don't use new Long
  SessionFactory mockedSessionFactory = mock(SessionFactory.class);
  Session session = mock(Session.class);
  Query query = mock(Query.class);

  when(mockedSessionFactory.getCurrentSession()).thenReturn(session);
  when(session.createQuery("FROM Person P where P.otdel.otdelId = :otdelId"))
      .thenReturn(query);
  when(query.setParameter("otdelId", otdelId)).thenReturn(query);
  when(query.list()).thenReturn(persons);

  PersonDAOImpl personDAO = new PersonDAOImpl(mockedSessionFactory);
  List<Person> result = personDAO.getPersonListByOtdelId(otdelId);

  verify(query).setParameter("otdelId", otdelId);
  assertEquals(result, persons);
}

您不需要验证是否调用了 getCurrentSession(),因为如果不是这样,被测代码将不会获得 session 。您不需要验证是否将正确的查询传递给 createQuery(),因为被测代码使用了不同的查询,Mockito 不会返回模拟查询(除非,当然,你使用 RETURNS_MOCKS )。

综上所述,我认为上述测试不是一个好的测试。测试几乎完全是代码的镜像,它不验证代码是否有效。换句话说,它是一个 change detector test .

我不会使用模拟框架来测试 PersonDaoImpl。相反,我会编写一个启动内存数据库的测试,使用一个模式文件,该文件也用于在生产中创建实际表。

我会使用模拟来测试依赖于 PersonDAO 的类。

关于java - 在java测试中没有收到错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29428583/

相关文章:

testing - 从命令行远程运行 Jmeter

java - 在 JUnit 测试用例中找不到测试方法

java - 如何使用一致的数据针对 Oracle UCM 执行集成测试?

java - 由于 Java 无法在 R 中运行 H2o

java - 如何直接在函数中传递int[]?

Java JsonPath 数组的长度

sql-server - 模拟慢速数据库连接

testing - Haskell:如何使用快速检查测试(响应式(Reactive))FSM?

java - 调用私有(private)静态 void 方法

java - 将 .dll 添加到 java 构建路径