无法在使用 @ExtendWith(SpringExtension.class) 运行的 Spring Boot 单元测试中注入应用程序上下文

Posted

技术标签:

【中文标题】无法在使用 @ExtendWith(SpringExtension.class) 运行的 Spring Boot 单元测试中注入应用程序上下文【英文标题】:could not inject application context in Spring Boot Unit test running with @ExtendWith(SpringExtension.class) 【发布时间】:2020-09-28 15:00:36 【问题描述】:

我正在尝试为使用 Spring boot 编写的 SOAP 端点编写单元测试。最初我使用@RunWith(SpringJUnit4ClassRunner.class) 编写测试,所有测试都成功执行。但是,当我尝试使用@ExtendWith(SpringExtension.class) 升级单元测试时,测试无法运行,因为它无法自动连接ApplicationContext 对象。下面是新旧代码的一部分。

旧代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
public class ServiceEndPointTest 
    @Autowired
    private ApplicationContext applicationContext;
    private MockWebServiceClient mockClient;

    @Before
    public void setUp() 
        mockClient = MockWebServiceClient.createClient(applicationContext);
    

新代码:


@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = TestConfiguration.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ActiveProfiles(profiles = "unittest")
public class ServiceEndPointTest 
   
    @Autowired
    private ApplicationContext applicationContext;
    private MockWebServiceClient mockClient;

    
    @Before
    public void setUp() 
        mockClient = MockWebServiceClient.createClient(applicationContext);
    

我在setUp() 中遇到错误,因为applicationContextnull

java.lang.IllegalArgumentException: 'applicationContext' must not be null

    at org.springframework.util.Assert.notNull(Assert.java:198)
    at org.springframework.ws.test.server.MockWebServiceClient.createClient(MockWebServiceClient.java:151)
    at com.test.ServiceEndPointTest.setUp(ServiceEndPointTest.java:80

不确定这里缺少什么。

请帮忙。

【问题讨论】:

【参考方案1】:

在迁移到 junit 5 期间,此类错误通常是由使用 junit 4 包中的 Junit 注释引起的。您提供的测试类包含 Junit 4-annotation @Before

我从 Junit 4 迁移到 Junit 5 的方法是在执行任何其他操作之前删除所有与 junit 4 相关的导入,即。删除org.junit.*-packages中的所有import语句。

不要保留这些:

import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;

相反,导入这些(等等):

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

删除旧的导入可确保没有“被遗忘”的导入仍然存在,导致出现看似不相关的错误消息的问题,例如您在此处遇到的错误消息。

另请参阅Junit 5 user guide,特别是annotations section

【讨论】:

感谢您的解决方案。 非常感谢,我使用的是@RunWith(SpringJUnit4ClassRunner.class),无法进入应用程序上下文,但使用@ExtendWith(SpringExtension.class) 可以。

以上是关于无法在使用 @ExtendWith(SpringExtension.class) 运行的 Spring Boot 单元测试中注入应用程序上下文的主要内容,如果未能解决你的问题,请参考以下文章

何时使用 @RunWith 以及何时使用 @ExtendWith

@ExtendWith(SpringExtension.class) 不工作

Spring JUnit 5 ExtendWith TestContainer

@ExtendWith(SpringExtension.class) 和 @ExtendWith(MockitoExtension.class) 有啥区别?

如何修复类型不匹配:@ExtendWith(SpringExtension::class) Class -> Class in intellij?

无法模拟 crudrepository 保存方法