1

I always wondered how much I should test my code (with unit tests).

Let's say I have this component:

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

To test it really thoroughly, I should mock Event and EntityManager. Which of these should I do then?

  • Verify that method createQuery on entityManager is called exactly once with the given JPQL statement.
  • Verify that method setParameter is called exactly once with the given parameters.
  • Verify that method getSingleResult is called exactly once.
  • Verify that event is fired with the given parameters exactly once.
  • Test that the correct user is returned.

All? It seems to me very invasive since every little change in my implementation results in change needed to be done in my tests.

I have two a little different questions which I think are related.

Q2: On arquillian webiste, you can read this:

Arquillian let's you ditch the mocks and write real tests.

Does it mean I shouldn't use mock objects? How can (with arquillian) I test my code really thoroughly then?

Q3: According to TDD, you should write tests first and then the implementation. But how do you want to do it if you don't have either the implementation or the api, so the tests won't compile?

4

2 回答 2

1

我一直想知道我应该对我的代码进行多少测试(使用单元测试)。

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

我这么说是因为你做的很少,大部分有趣的事情都发生在数据库或 ORM 中,这就是问题的来源。

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

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

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

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

根据 TDD,您应该先编写测试,然后再编写实现。但是,如果您没有实现或 api,您想怎么做

这些测试可以帮助您制定 API。

所以测试不会编译?

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

于 2012-06-15T12:43:16.693 回答
1

Q3:按照TDD,你应该先写测试,再写实现。但是,如果您既没有实现,也没有 api,那么您想怎么做,所以测试将无法编译?

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

于 2012-06-11T20:58:37.017 回答