在单元测试中使用SpringRunner是否可以? [英] Is it OK to use SpringRunner in unit tests?

查看:143
本文介绍了在单元测试中使用SpringRunner是否可以?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正与同事争论这种方法。他们说只在集成或功能级别上使用SpringRunner。

We are arguing about this approach with my colleagues. They say to use SpringRunner only on integration or functional levels.

问题是在下面的级别使用它的优点和缺点是什么?

The question is what pros and cons of using it in level below?

例如我有简单的bean:

For example I have simple bean:

public class RewardDurationCalculator {

    private Clock clock;

    public OptionalLong calculate(DurationType durationType, List<Pass> passes) {
        long now = Instant.now(clock).getEpochSecond();
        switch (durationType) {
            case FULL_PASS:
                return getCurrentPassDuration(passes, now);
            case TILL_THE_END_OF_THE_CURRENT_ACTIVE_PASS:
                return getTimeInCurrentPassLeft(passes, now);
        }
        return OptionalLong.empty();
    }

    private OptionalLong getCurrentPassDuration(List<Pass> passes, long now) {
        return passes.stream()
                .filter(currentPass(now))
                .mapToLong(Pass::getDuration)
                .findFirst();
    }

    private OptionalLong getTimeInCurrentPassLeft(List<Pass> passes, long now) {
        return passes.stream()
                .filter(currentPass(now))
                .mapToLong(pass -> getEndTs(pass) - now)
                .findFirst();
    }

    private Predicate<Pass> currentPass(long now) {
        return pass -> pass.getStartTs() >= now && now <= getEndTs(pass);
    }

    private long getEndTs(Pass pass) {
        return pass.getStartTs() + pass.getDuration();
    }

}

正在做一些计算逻辑。对于它我也有spring配置:

that is doing some calculation logic. For it I have also spring config:

@Configuration
public class RewardDurationCalculatorConfiguration {

    @Bean
    public RewardDurationCalculator rewardDurationCalculator(Clock clock) {
        return new RewardDurationCalculator(clock);
    }

}

为什么我不能写它的单元测试如下:

So why can't I write unit test for it like this:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = RewardDurationCalculatorConfiguration.class)
public class RewardDurationCalculatorTest {

    @MockBean
    private Clock clock;
    @Autowired
    private RewardDurationCalculator rewardDurationCalculator;

    @Test
    public void testCalculateCurrentPassDurationShouldBeReturnedIfPassWasCreatedRightNow() {
        rewardDurationCalculator.calculate(DurationType.FULL_PASS, Collections.emptyList());
    }

}

使用时我可以面对什么这种做法?

What cons I can face with using such approach?

推荐答案

我倾向于同意你的同事。

I tend to agree with your colleagues.

单元测试应该只测试小的代码单元,通常是方法,理想情况下只运行被测单元而不执行任何其他代码(私有方法除外)。

Unit tests should only test small units of code, typically methods, ideally exercising only the unit under test without executing any other code (with the exception of private methods).

这样做的一个原因是单元测试应该尽可能快地执行,因此开发人员可以在对代码进行的每次小的更改之后尽可能经常地运行它们。您希望从单元测试中获得即时反馈。即使加载Spring上下文通常很安静并且只增加了大约一秒的测试执行时间,如果你每天执行测试几百次,这一秒就会变得很烦人,因为例如,一个类的广泛重构。

One reason for this is that unit tests should execute as fast as possible, so developers can run them as often as possible, after every small change they make to the code. You want to get instant feedback from unit tests. Even if loading the Spring context is usually quiet fast and adds just about a second to the execution time of your test, this one second adds up to being annoying if you execute the test a few hundred times per day as you should when doing, for example, extensive refactoring of a class.

坚持这个规则的另一个原因是它迫使你编写高度解耦的类。如果你不能为只运用该类而没有其他内容的类编写单元测试,则可能表明你应该重新考虑你的类设计。

Another reason to stick to this rule is that it forces you to write highly decoupled classes. If you can't write unit tests for a class that exercise only that class and nothing else, it can be a sign that you should rethink your class design.

当你在整个Spring上下文中进行测试,通过这个定义,它不再是一个单元测试,而是一个集成测试,因为你也在测试整个Spring配置,bootstrapping,autowiring等,i。即将类集成到Spring应用程序中。

When you ramp up the whole Spring context for a test, by this definition, it is not a unit test anymore, but an integration test, because you are also testing the whole Spring configuration, bootstrapping, autowiring etc, i. e. the integration of your classes into a Spring application.

这篇关于在单元测试中使用SpringRunner是否可以?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆