在Spring中进行单元测试:将依赖注入到被测试的组件中。

7 浏览
0 Comments

在Spring中进行单元测试:将依赖注入到被测试的组件中。

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

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

logger依赖通过以下配置注入:

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

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

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

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

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

然而,logger对象在MyController中没有被"autowired"(注意我不想mock logger对象),这导致了空指针引用。

我漏掉了什么?

0
0 Comments

在Spring中进行单元测试时,我们不应该使用任何Spring配置。我们应该简单地实例化组件,并手动注入依赖(通常是虚拟的依赖)。

你使用了字段注入,这使得情况变得有点复杂。如果使用构造函数注入,你只需要做以下操作:

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

然而,即使使用字段注入,Mockito也可以帮助你注入虚拟依赖,这要归功于@InjectMocks@Mock@RunWith(MockitoJUnitRunner.class)注解:

private Logger logger = LoggerFactory.getLogger(MyController.class);
private MyController controller;
public void prepare() {
    MockitoAnnotations.initMocks(this);
}

话虽如此,如果我没记错的话,你没有使用@RunWith(SpringJUnit4ClassRunner.class),所以你的测试运行器对Spring一无所知,因此不会创建或使用任何Spring配置。

是的,我认为真正的问题在于SpringJUnit4ClassRunner。这更像是一个集成测试而不是单元测试。

看来我在使用Spring进行单元测试时走错了路。在单元测试中使用字段注入并将Spring排除在外似乎是正确的做法。谢谢你的解释。

0
0 Comments

问题的出现原因:在进行单元测试时,通常不应该包含Spring配置。然而,如果仍然希望在Spring管理的bean上执行单元测试,可以使用SpringExtension的参数解析器。

解决方法:可以使用SpringExtension的参数解析器来在单元测试中注入依赖。在这个例子中,SpringExtension会自动使用,但是对于Controller测试,需要显式地添加。

具体的解决方法如下:

1. 在测试类上添加注解@ExtendWith(SpringExtension.class),以启用SpringExtension。

2. 在注解@ExtendWith(SpringExtension.class)中指定需要注入依赖的类,例如MyController.class、Myconfig.class和MyTestConfig.class。

3. 运行单元测试。

以下是示例代码:

import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
public class MyContollerTest {
    // 测试方法
}

通过以上方法,可以在进行单元测试时,将依赖注入到待测试的组件中。

0