【问题标题】:Spring 5 with JUnit 5 + Mockito - Controller method returns null带有 JUnit 5 + Mockito 的 Spring 5 - 控制器方法返回 null
【发布时间】:2018-07-21 12:26:14
【问题描述】:

我尝试测试在MainController 中定义的名为loadData 的方法,它以字符串形式返回结果。尽管此方法实际上在 Web 应用程序在 servlet 容器上运行时(或在我调试代码时)返回数据,但当我从基于 JUnit 5Mockito 的测试类调用它时,没有数据返回。

这是我的配置:

@ContextConfiguration(classes = {WebAppInitializer.class, AppConfig.class, WebConfig.class})
@Transactional
@WebAppConfiguration
public class TestMainController {

    @InjectMocks
    private MainController mainController;

    private MockMvc mockMvc;

    @BeforeEach
    public void init() {
        mockMvc = MockMvcBuilders.standaloneSetup(this.mainController).build();
    }

    @Test
    public void testLoadData() throws Exception {
        MvcResult mvcResult = mockMvc
                .perform(MockMvcRequestBuilders.get("/loadData.ajax"))
                .andExpect(MockMvcResultMatchers.status().isOk()).andReturn();

        Assertions.assertNotNull(mvcResult.getResponse().getContentAsString(), "response should not be null");
    }

}

由于java.lang.NullPointerException 导致测试失败,因为this.mainControllernull

环境详情:

Spring version: 5.0.3
JUnit version: 5.0.3
mockito version: 1.9.5
hamcrest version: 1.3
json-path-assert version: 2.2.0

编辑:这里是MainControllerloadData方法:

@RequestMapping(value = "/loadData.ajax", method = RequestMethod.GET)
public String loadData(HttpServletRequest request, HttpServletResponse response) {
    List list = mainService.loadData(); // starts a transaction and invokes the loadData method of mainDAO repository which basically loads data from the database
    return JSONArray.fromObject(list).toString();
}

【问题讨论】:

  • 你不用MockHttp直接调用控制器的方法。你模拟一个 URL 的使用:docs.spring.io/spring-security/site/docs/current/reference/html/…
  • 假设我要测试的 URL 是loadData.ajax。你能指导我设置测试环境吗?通过您分享的指南尝试了以下操作,但没有运气:mockMvc.perform(get("/loadData.ajax"));
  • 添加您的MainController。你的测试有什么奇怪的,你有一个 web 配置和一个常规配置,你不应该只有一个吗?
  • @M.Deinum AppConfig 用于创建 session factorytransaction manager bean。 WebConfig 实现 WebMvcConfigurer 并定义了所有其他必需的 bean,包括 view revolversinterceptorstasks 等。
  • 在同一个测试类中不可能声明@SpringJUnitWebConfig @SpringJUnitConfig。 Spring 只会尊重其中的 一个,即它找到的第一个。

标签: spring spring-mvc junit mockito junit5


【解决方案1】:

您可以直接调用控制器方法,就像我们对服务方法所做的那样,但不建议这样做。使用 MockMvc,您检查 headerrequest param mapping 是否正确。另外,您还检查 端点映射 是否正确。另外Request METHOD也是正确的。如果您通过直接调用控制器方法来测试代码,所有这些都无法测试。

您可以尝试的一件事是,不要在独立上下文中创建新对象,而是使用 Mock.即

mockMvc = MockMvcBuilders.standaloneSetup(this. mainController).build();

在调用时,这样做

MvcResult mvcResult = mockMvc
    .perform(MockMvcRequestBuilders.get("/loadData.ajax"))
    .andExpect(MockMvcResultMatchers.status().isOk()).andReturn();

断言,你想要什么

Assert.assertEquals("response does not match", mvcResult.getResponse().getContentAsString(),
    "some expected response");

您正在获取 null 或 400 或 404 http 状态?

如果你得到 400,那么请检查标题和请求。参数是否合适。如果您收到 404,请检查 URL 路径。 /loadData.ajax ,假设这是您在控制器方法中的请求映射路径。

【讨论】:

  • mockMvc被初始化时,将NullPointerException作为this.mainController在行上发现为空。
  • 请在类级别添加 @RunWith(MockitoJUnitRunner.class)。像这样的东西。 @RunWith(MockitoJUnitRunner.class) public class TestMainController { 然后你的变量 mainController 将被初始化
  • 找不到RunWith 类,它是JUnit 4 的一部分。
  • 导入 org.junit.runner.RunWith;我在 junit:4.12 版本下看到了这个。并在 build.gradle testCompile("junit:junit:4.12")
  • 类路径上的 JUnit 4 和 5?听起来不太好,因为注释是在不同的包上定义的。获取异常No tests found in TestMainController Haven't you forgot @Test annotation?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 2021-02-26
  • 2019-07-01
  • 2020-08-13
  • 2021-07-01
  • 1970-01-01
相关资源
最近更新 更多