【发布时间】:2018-08-12 06:55:51
【问题描述】:
我正在尝试使用 JUnit 5 测试我的 Spring 5 Web 控制器。 测试控制器的两种方法(如 spring 文档中提到的)总是给我空指针。
这是我的测试课
import com.lacunasaurus.gamesexplorer.test.configuration.TestBackEndConfiguration;
import com.lacunasaurus.gamesexplorer.test.configuration.TestWebConfig;
import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
@RunWith(JUnitPlatform.class)
@ExtendWith(SpringExtension.class)
@WebAppConfiguration()
@ContextConfiguration(classes = {TestWebConfig.class, TestBackEndConfiguration.class})
public class TestAuthenticationCreateAccountController {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
// this.mockMvc = MockMvcBuilders.standaloneSetup(new AuthenticationCreateAccountController()).build();
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void getAccount() throws Exception {
// Here i've got an null pointer
mockMvc.perform(get("/"));
}
}
这是我用于测试的 Web 配置
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ComponentScan(basePackages = {"com.lacunasaurus.gamesexplorer.web"})
public class TestWebConfig implements WebMvcConfigurer, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
现在是我的控制器
@Controller
@RequestMapping("/create-account")
public class AuthenticationCreateAccountController {
@Autowired
UserAccountValidator accountValidator;
@Autowired
AuthenticationService authenticationService;
@GetMapping
public String navigate() {
return "authentication/create-account";
}
@ModelAttribute("userAccount")
public UserAccount setDefaultAccount() {
return new UserAccount();
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(accountValidator);
}
@PostMapping
public String createAccount(@Validated UserAccount userAccount, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "authentication/create-account";
}
authenticationService.createUserAccount(userAccount);
return "authentication/create-account";
}
}
编辑:IDE 给出的堆栈跟踪
java.lang.NullPointerException at com.lacunasaurus.gamesexplorer.test.controller.TestAuthenticationCreateAccountController.getAccount(TestAuthenticationCreateAccountController.java:41)
Results :
Tests in error:
TestAuthenticationCreateAccountController.getAccount:41 NullPointer
我已经用 junit 5 和 spring 测试了我的后端,一切正常。
感谢那些帮助我了解如何测试控制器的人:)
【问题讨论】:
-
您在询问异常,但不要发布异常的堆栈跟踪。阅读它是解决问题的第一步。请注意,您正在混合使用 JUnit 4 和 JUnit 5 类和注释,这没有任何意义。阅读 JUnit 5 的文档。
-
好的,现在我们知道 null 是 mockMvc。为什么它是空的?它应该在 setup() 方法中初始化。因此,如果它为空,则意味着 setup() 没有被调用。为什么不叫呢?因为它没有使用任何可以调用它的 JUnit 5 注释进行注释。
Before是一个 JUnit 4,因此是无关紧要的注释。RunWith也是如此。 -
是的,对不起,我添加了堆栈跟踪,但这个不是太明确如果我在这里寻求帮助,那是因为我在文档中没有看到一些东西,并且邀请阅读解决这个问题对我没有太大帮助,特别是如果你的经验让你立即理解它:(无论如何,你强调使用 Junit 4(我在我的 pom.xml 中绝对没有提到)我可以看到问题来自注释@Before。谢谢你:)
-
非常明确。它说某事是空的,因此在第 41 行,在 TestAuthenticationCreateAccountController 的方法 getAccount() 内导致 NullPointerException。在这一行中唯一可以为空的是 MockMvc。其余的都是由此推导出来的。我邀请人们阅读,因为我注意到大多数新手甚至不阅读文档,甚至一次也不阅读。他们尝试随机的事情,然后寻求帮助。阅读文档需要一些时间,但可以了解全局,发现功能,并且不会犯愚蠢的错误。最后,收获是巨大的。
-
我们是同时写的,确实问题出在之前我改成BeforeAll。很好的分析;)
标签: spring-mvc junit junit5 spring-test-mvc