如何使用Junit5测试弹簧5控制器

Lac*_*rus 5 junit spring-mvc spring-test-mvc junit5

我正在尝试使用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("/"));
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我测试的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;
    }

}
Run Code Online (Sandbox Code Playgroud)

而现在我的控制器

  @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";
   }
  }
Run Code Online (Sandbox Code Playgroud)

编辑:IDE给出的堆栈跟踪

  java.lang.NullPointerException at com.lacunasaurus.gamesexplorer.test.controller.TestAuthenticationCreateAccountController.getAccount(TestAuthenticationCreateAccountController.java:41)

Results :

Tests in error: 
    TestAuthenticationCreateAccountController.getAccount:41 NullPointer
Run Code Online (Sandbox Code Playgroud)

我已经用junit 5和spring测试了我的后端,一切都运行良好.

感谢帮助我了解如何测试控制器的那些人:)

Lac*_*rus 6

控制器的新测试:

@ExtendWith(SpringExtension.class)
@WebAppConfiguration()
@ContextConfiguration(classes = {TestWebConfig.class, TestBackEndConfiguration.class})
@TestInstance(Lifecycle.PER_CLASS)
public class TestAuthenticationCreateAccountController {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @BeforeEach
    void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    void getAccount() throws Exception {
        mockMvc.perform(get("/toto")).andExpect(status().isOk());
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 删除@RunWith(JUnitPlatform.class).这不是必需的.这已被JUnit5中的@ExtendWith(SpringExtension.class)取代,你已经拥有了它. (4认同)
  • @BeforeAll 方法必须具有 void 返回类型,不能是私有的,并且默认情况下必须是静态的:https://junit.org/junit5/docs/5.0.3/api/index.html?org/junit/jupiter/ api/BeforeAll.html (2认同)

小智 6

如果您使用 Junit5,请参阅此参考

@ExtendWith(MockitoExtension.class)  // For Junit5
public class TestAuthenticationCreateAccountController {

    @Mock
    private WebApplicationContext wac;

    @InjectMocks
    private AuthenticationCreateAccountController ac;

    private MockMvc mockMvc;

    @BeforeEach // For Junit5
    public void setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(ac).build();

    }

    @Test
    public void getAccount() throws Exception {
        mockMvc.perform(get("/"));
    }

}
Run Code Online (Sandbox Code Playgroud)