我应该对我的代码进行单元测试

时间:2012-06-11 20:51:25

标签: testing mocking

我总是想知道我应该测试多少代码(使用单元测试)。

假设我有这个组件:

@Stateless
public class UserManager {
    @PersistenceContext
    EntityManager entityManager;

    @Inject
    Event<UserEvent> event;

    public User getUserByUsername(String username) {
        User user = entityManager
                     .createQuery("SELECT u FROM User u WHERE u.username = :username", User.class)
                     .setParameter("username", username)
                     .getSingleResult();
        event.fire(new UserEvent("some message"));

        return user;
    }
}

要彻底测试它,我应该模拟Event和EntityManager。 我应该做以下哪些?

  • 使用给定的JPQL语句验证entityManager上的方法createQuery是否只调用一次。
  • 验证方法setParameter是否使用给定参数调用一次。
  • 验证方法getSingleResult只调用一次。
  • 确认使用给定参数触发事件一次。
  • 测试是否返回了正确的用户。

所有?在我看来,这是非常具有侵略性的,因为我的实现中的每一个小变化都会导致我的测试需要进行更改。

我认为有两个不同的问题与我有关。

Q2:在arquillian webiste上,您可以阅读:

  

Arquillian让你放弃嘲笑并编写真正的测试。

这是否意味着我不应该使用模拟对象?怎么能(用arquillian)我真的彻底测试我的代码呢?

问题3:根据TDD,您应首先编写测试然后再执行。但是如果你没有实现或api,你想怎么做呢,所以测试不会编译?

2 个答案:

答案 0 :(得分:1)

  

问题3:根据TDD,您应首先编写测试然后再执行。但是如果你没有实现或api,你想怎么做呢,所以测试不会编译?

测试应该编译但是失败。您可以在类定义中存根方法,以便在编写测试时显示它们,但在运行测试之前不应该实现方法体。

答案 1 :(得分:1)

  

我总是想知道我应该测试多少代码(使用单元测试)。

如果您的DAL中没有业务逻辑,那么我会说:不要编写(纯)单元测试,编写集成测试。首先编写集成测试测试。

我这样说是因为你做的很少,大多数有趣的事情发生在数据库或ORM中,这就是问题的根源所在。

我可能会考虑的唯一(纯)单元测试用于显示事件被触发。

我不知道Arquillian是如何工作的,并且鉴于需要少量“世界”,我可能不会将它用于此测试。相反,我只是在测试方法中新建一个EntityManager并将其传递下去。我可能会嘲笑Event<UserEvent>

  

这是否意味着我不应该使用模拟对象?

模拟(和其他假货)是一种工具。它们非常有用。但它们并不能解决所有问题,也不能用于测试每件事。

  

根据TDD,您应首先编写测试然后再执行。但是如果你没有实现或api

,你想怎么做呢?

测试可帮助您计算API。

  

所以测试不会编译?

失败。修复故障并重新运行测试。