java Spring 中的单元测试:将依赖项注入到被测组件中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34231426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 22:38:11  来源:igfitidea点击:

Unit test in Spring: injecting a dependency into a component under test

javaspringunit-testing

提问by Damian Nadales

I have a very simple rest controller:

我有一个非常简单的休息控制器:

@RestController
public class MyController {
    @Autowired
    public Logger logger;

The logger dependency gets injected via the following configuration:

记录器依赖项通过以下配置注入:

@Configuration
public class MyConfig {
    @Bean
    public Logger logger() {
        return LoggerFactory.getLogger(MyController.class);
    }

If I run the Spring application that contains the controller then everything works fine. However, I cannot manage to achieve this dependency injection when running my unit tests. In this case I have the following test configuration:

如果我运行包含控制器的 Spring 应用程序,则一切正常。但是,在运行单元测试时,我无法实现这种依赖注入。在这种情况下,我有以下测试配置:

@Configuration
@Profile("test")
public class MyTestConfig {
    @Bean
    public Logger logger() {
        return LoggerFactory.getLogger(MyCOntroller.class);
    }

And this is the relevant part of my unit tests code:

这是我的单元测试代码的相关部分:

@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration(classes = MyTestConfig.class)
@ActiveProfiles("test")
public class MyContollerTest {

However the logger object does not get "autowired" in MyController(note that I do not want to mock the logger object), which results in a null pointer reference.

但是,记录器对象不会“自动装配” MyController(请注意,我不想模拟记录器对象),这会导致空指针引用。

What am I missing?

我错过了什么?

回答by JB Nizet

A unit test shouldn't use any Spring configuration. You should simply instantiate your component, and inject dependencies (usually fake ones) manually.

单元测试不应使用任何 Spring 配置。您应该简单地实例化您的组件,并手动注入依赖项(通常是假的)。

You used field injection, which makes it a bit harder. With constructor injection, all you would need to do is

您使用了字段注入,这使它变得有点困难。使用构造函数注入,您需要做的就是

Logger logger = LoggerFactory.getLogger(MyController.class);
MyController controller = new MyController(logger);

Mockito can help injecting fake dependencies for you, though, even when using field injection, thanks to the @Mock, @Spyand @InjectMocksannotations:

Mockito 可以帮助您注入虚假的依赖项,即使在使用字段注入时,感谢@Mock,@Spy@InjectMocks注释:

@Spy
private Logger logger = LoggerFactory.getLogger(MyController.class);

@InjectMocks
private MyController controller;

@Before
public void prepare() {
    MockitoAnnotations.initMocks(this);
}

That said, if I'm not mistaken, you're not using @RunWith(SpringJUnit4ClassRunner.class), so your test runner doesn't know anything about Spring, and thus doesn't create or use any Spring configuration.

也就是说,如果我没记错的话,您没有使用@RunWith(SpringJUnit4ClassRunner.class),因此您的测试运行程序对 Spring 一无所知,因此不会创建或使用任何 Spring 配置。