运行 Junit 测试用例时“加载 ApplicationContext 失败”

Posted

技术标签:

【中文标题】运行 Junit 测试用例时“加载 ApplicationContext 失败”【英文标题】:"Failed to load ApplicationContext" while running Junit Test Case 【发布时间】:2020-07-30 11:59:25 【问题描述】:

我知道关于同一个问题已经有多个问题,但在我的上下文中我无法从其中的任何一个中得到任何解决方案,所以在这里发布。我使用WebMvcTest 注释创建了一个简单的Junit 测试用例。

我的测试班如下:

@WebMvcTest(controllers = EmployeeResourceController.class)
public class EmployeeResourceControllerTest 
@Autowired
private MockMvc mvc;

private static Employee employee;

@MockBean
private EmployeeService employeeService;

@BeforeAll
static void setup() 
    employee = new Employee();



@Test
public void listAllEmployeeTest() throws Exception 
    List<Employee> allEmployee = Arrays.asList(employee);
    Mockito.when(employeeService.listAllEmployee()).thenReturn(allEmployee);
    mvc.perform(MockMvcRequestBuilders.get("url").accept(MediaType.APPLICATION_JSON))
            .andExpect(MockMvcResultMatchers.status().isOk());



我得到的异常如下:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:95)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
    at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:341)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:346)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:341)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
    at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
    at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:340)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:263)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:256)
    at java.util.Optional.orElseGet(Optional.java:267)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:255)
    at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:29)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:108)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:107)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:71)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:107)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:107)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:75)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)

由于此应用程序无法找到用于自动装配的 EmployeeServiceImpl。

【问题讨论】:

【参考方案1】:

在课堂上使用以下annotation RunWith, SpringBootTest &amp; WebAppConfiguration

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.MOCK)
@WebAppConfiguration
public class EmployeeResourceControllerTest 
@Autowired
private MockMvc mvc;

private static Employee employee;

@MockBean
private EmployeeService employeeService;

@BeforeAll
static void setup() 
    employee = new Employee();



@Test
public void listAllEmployeeTest() throws Exception 
    List<Employee> allEmployee = Arrays.asList(employee);
    Mockito.when(employeeService.listAllEmployee()).thenReturn(allEmployee);
    mvc.perform(MockMvcRequestBuilders.get("url").accept(MediaType.APPLICATION_JSON))
            .andExpect(MockMvcResultMatchers.status().isOk());



【讨论】:

感谢您的回答,但您能否解释一下为什么 WebMvcTest 不正确。它用于切片测试,而集成测试需要 SpringBootTest 注解。此外,在我的另一个应用程序中,类似类型的测试用例仅使用 WebMvcTest Annotation 即可完美运行。

以上是关于运行 Junit 测试用例时“加载 ApplicationContext 失败”的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.IllegalStateException:运行 Junit 测试用例时无法加载 ApplicationContext

Junit测试用例在STS中成功运行,但无法通过Jmeter运行。

JUnit 测试和集成测试 - Jenkins - Cucumber

Junit - 优先级测试(FixMethodOrder Test)

如何在 bitrise 上运行测试用例时查看模拟器

Android:运行测试用例时:无法确定任务':app:compileDebugAndroidTestJavaWithJavac'的依赖关系