Does it make sense to Unittest wrapper methods

时间:2015-06-26 09:34:42

标签: java unit-testing jmockit

This question is somewhat philosophical. Given i have a Method like this:

public List<String> getStuffByName(@NotNull String name) throws SomeException {
        return someDependency.createQuery().byName(name).list().stream()
                .map(execution -> execution.getProcessInstanceId())
                .collect(Collectors.toList());
}

Basically all it does is call a dependencies method and then process it using the stream api.

A Unittest - in a strict understanding(?) - is only testing one isolated unit. So i would Mock the dependencies, as i assume they also are already tested units themselves.

If I go through with this, i end up with a Method that exclusively consists of stuff that is tested elsewhere.

Eg my JMockit Test would look like this:

public void test_get_processes_for_bkey_2(@Mocked ExecutionQuery query,
                                              @Mocked List<String> processes,
                                              @Mocked List<Execution> executions,
                                              @Mocked Stream<Execution> e_stream,
                                              @Mocked Stream<String> pid_stream,
                                              @Mocked Stream<String> pdef_stream

    ) {
    new Expectations() {
        {
            someDependency.createQuery(); result = query;
            query.byName("somefilter"); result = query;
            query.list(); result = executions;
            executions.stream(); result = e_stream;
            e_stream.map((Function) any); result = fin_stream;
            fin_stream.collect((Collector) any); result = processes;
            processes.size(); result = 2;
        }
    };

    assertEquals(tested.getStuffByName("somefilter").size(), 2);
}

But what does this test really tell me?

In test-driven-development, would i omit tests of such "wrapper" methods?

What would a professional approach to test this be, independent of Jmockit or other frameworks?

4 个答案:

答案 0 :(得分:4)

A&#34;专业方法&#34;测试这将是模拟任何东西。一个好的测试应该尽可能真实,同时保持足够快速和稳定。

单元测试(在纯/严格意义上,单元通过模拟与其依赖关系隔离)被高估。这不是我说的;像Kent Beck(TDD的主要创作者和#34;)和Martin Fowler这样的作家并不是&#34;纯粹&#34;单元测试(例如,参见Is TDD Dead?)。

模仿最适用于特殊情况,出于实际原因,您无法在没有它的情况下轻松编写测试。根据我自己的经验,集成测试(没有或最小的模拟)已被证明更好。

答案 1 :(得分:1)

You do want to test all public methods, including ones that wrap logic from other methods. A passing unit test for this method tells you several important things:

  • The method getStuffByName exists,
  • The signature of getStuffByName is what you expect,
  • The logic of getStuffByName is pinned down by the checks in the unit test.

If someone decides to re-implement your getStuffByName method with loops instead of streams, because they wanted to back-port your code to an earlier version of Java, passing the unit test would let them know that their conversion worked correctly.

答案 2 :(得分:1)

The main idea behind unit tests is that they test 'units' of code, not the whole infrastructure or interaction between components. If you write a method like

public int sum(int a, int b){
  return a + b;
}

you are still using wrappers (int/Integer and the + method), but in that case you would write unit tests to check that your sum method works, wouldn't you? Because you might have done something like:

public int sum(int a, int b){
  return a;
}

and this is definitely a bug - but still, it's just a wrapper!

Okay, there are unit tests that know a bit more about the underlying system (white-box testing) and unit tests that know nothing about what is inside (black-box, no assumptions). So, it depends on you whether you want to test something or not - if you think your code is bug-free just because "it's just a wrapper", then we should stop writing tests, because everything can be thought as a wrapper.

答案 3 :(得分:0)

The contract of the method is to execute the query having the given name, and return the process instance IDs of the Execution instances returned by the query. Whether your method uses streams, or a for loop, or anything to do that is irrelevant.

So I would only stub the query and make it return a real list of 2 or 3 executions. Based on that list returned by the query, I would check that the returned List contains the appropriate 2 or 3 IDs, in the correct order.