【问题标题】:Spring Boot unit test runs the whole programSpring Boot 单元测试运行整个程序
【发布时间】:2020-07-09 01:53:15
【问题描述】:

我想用 Spring Boot 实现一个集成测试。我从spring-boot-starter-test 依赖项开始,版本2.2.5.RELEASE

我有以下组件:

@Component
public class MyMath {

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

}

主程序如下所示:

@SpringBootApplication
public class Main implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @Autowired
    private MyMath myMath;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(myMath.add(2, 3));
    }

}

它按预期工作 - 到目前为止,一切都很好。我想添加一个单元测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyMathTest {

    @Autowired
    private MyMath myMath;

    @Test
    public void testSaveAndList() {
        assertEquals(5, myMath.add(2, 3));
    }

}

这也有效,但根据日志它执行整个程序。我不想运行程序本身,只想运行MyMath.add() 函数。我该怎么做?

到目前为止,我尝试了以下方法:

  • @RunWith(SpringJUnit4ClassRunner.class) 提供了相同的结果。
  • 省略@SpringBootTest 结果NoSuchBeanDefinitionException
  • 重新格式化代码以使用 bean 而不是像下面这样的组件。

MyMath 无注解:

public class MyMath {

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

}

Main 保持不变。

@Configuration
public class AppConfig {

    @Bean
    public MyMath getMyMath() {
        return new MyMath();
    }
}

还有测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyMathTest {

    @Autowired
    private MyMath myMath;

    @Test
    public void testSaveAndList() {
        assertEquals(5, myMath.add(2, 3));
    }

}

所以我不能做的是在不运行整个程序的情况下测试一个组件。有什么可以帮助我的吗?谢谢!

【问题讨论】:

  • 我认为你真的不需要 Spring 提供的任何东西来运行这个测试。尝试从测试类中删除所有与 Spring 相关的注释,不要注入 MyMath,而是在测试类的某处使用 new 实例化它。只要 @Test 注释仍然存在,JUnit 就应该选择它。尝试使用非 Spring 测试运行器,更多信息 here
  • 是的,测试一个 add 函数真的不需要任何 Spring 的东西。但是,如果我有一个具有自动装配依赖关系的组件,并且我想测试它怎么办?我故意不想让这个例子过于复杂。

标签: java spring spring-boot junit spring-boot-test


【解决方案1】:

您无需重构代码。保持 MyMath 类的原样

@Component
public class MyMath {

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

像这样改变你的测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyMath.class)
public class MyMathTest {

    @Autowired
    private MyMath myMath;

    @Test
    public void testSaveAndList() {
        assertEquals(5, myMath.add(2, 3));
    }

}

如果您的 MyMath 类具有自动装配的其他依赖项,这会变得有点复杂。然后你必须使用模拟。

【讨论】:

  • 谢谢,这正是我想要的!
【解决方案2】:

如果您的 MyMath 类如此简单,我不会使用 Spring 来初始化它。没有必要,更重要的是 - junit 应该很快。因此,与其使用 Spring Context 运行测试,不如将其更改为简单的 JUnit 并像普通对象一样创建 MyMath:

public class MyMathTest {

    private MyMath myMath = new MyMath();

    @Test
    public void testSaveAndList() {
        assertEquals(5, myMath.add(2, 3));
    }

}

【讨论】:

  • 感谢您的回答。确实,我特意创造了这样一个简单的例子。这里的重点不是加法器,而是如何在 Spring 中创建单元测试。
  • 如果你真的需要 Spring 来创建 JUnit 测试,你应该总是问这个问题。大多数情况下,您可以使用简单的构造函数创建对象,以便您的测试运行得更快。使用 SpringBootTest 注解的测试被认为是集成测试。
猜你喜欢
  • 2017-02-20
  • 2018-11-29
  • 1970-01-01
  • 2017-01-30
  • 2016-05-28
  • 1970-01-01
  • 2020-07-28
  • 2019-02-05
相关资源
最近更新 更多