当前位置: 首页 > 知识库问答 >
问题:

Junit5: WebMvcTest返回404。也许是因为我没有嘲笑你的方法?

纪实
2023-03-14

前言:我正在学习Java、Spring Boot和总体。。。带有Java/Spring Boot的TDD。

使用的版本:

    Spring启动
  • Java17
  • 6月5日

这是我的控制器:

@RestController
@RequestMapping("/api/v1/login")
public class LoginController {

    @Autowired
    private JwtAuthentication jwtAuthentication;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private JwtUserDetailService jwtUserDetailService;

    @PostMapping
    public ResponseEntity<?> createAuthenticationToken(@RequestBody UserEntity userEntity) throws Exception {
        jwtAuthentication.authenticate(userEntity.getUsername(), userEntity.getPassword());
        final UserDetails userDetails = jwtUserDetailService.loadUserByUsername(userEntity.getUsername());
        final String token = jwtTokenUtil.generateToken(userDetails);
        return ResponseEntity.ok(new JwtResponse(token));
    }
}

相关的autowiredJwtAuthentication

@Component
public class JwtAuthentication {

    @Autowired
    private AuthenticationManager authenticationManager;

    private static final long serialVersionUID = -20220210203900L;

    public void authenticate(String username, String password) throws BadCredentialsException {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (BadCredentialsException e) {
            throw new BadCredentialsException("INVALID_CREDENTIALS", e);
        }
    }
}

我为JwtAuthentication本身编写了测试,没有任何问题,现在我需要测试控制器。

这是我的测试:

@ExtendWith(SpringExtension.class)
@WebMvcTest(LoginControllerTest.class)
class LoginControllerTest {

    @Autowired
    private MockMvc mvc;

    @Autowired
    private ObjectMapper objectMapper;
    
    @MockBean
    private JwtAuthentication jwtAuthentication;
    
    
    @Test
    void testCanLogin() throws Exception {

        UserEntity userEntity = new UserEntity();
        userEntity.setUsername("username");
        userEntity.setPassword("password");
        
        mvc.perform(post("/api/v1/login/").contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsBytes(userEntity))).andExpect(status().isOk());
    }
}

但我得到的是404而不是200。

我读到,原因是缺少对底层方法的嘲弄。实际上,这些控制器测试并不会启动整个配置(等等)。在S.O.上找不到答案。。

因此,我认为解决方案需要在测试中添加一个“简单的”

@Test
void testCanLogin() throws Exception {

UserEntity userEntity = new UserEntity();
userEntity.setUsername("username");
userEntity.setPassword("password");

// I think I need some code here:
// pseudocode    when(jwtAuthentication.authenticate("username", "password").then .... I DON'T KNOW HERE!

mvc.perform(post("/api/v1/login/").contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsBytes(userEntity))).andExpect(status().isOk());
    }

共有1个答案

经骁
2023-03-14

404是因为没有控制器来处理请求。

这是因为您在@WebMvcTest中指定了错误的控制器,因此要测试的控制器未包含在spring容器中。因此,对以下内容的更改应该可以解决问题:

@WebMvcTest(LoginController.class)
class LoginControllerTest {

    @MockBean
    private JwtAuthentication jwtAuthentication;

    @MockBean
    private JwtTokenUtil jwtTokenUtil;

    @MockBean
    private JwtUserDetailService jwtUserDetailService;

}

还要注意以下几点:

  • 我删除了@extendedwith(SpringExtension.class),因为@WebMvcTest已经包含了它
  • @WebMvcTest将只启用与web层相关的bean(参见此),而JwtTokenUtilJwtUserDetailService不属于它。所以你必须使用@MockBean来模拟它们
 类似资料:
  • 以下是日志供参考: IllegalStateException:无法转换名为com.xyz.TestLoad的类。原因:java.io.ioException:无效常量类型:在org.powermock.core.classloader.mockClassLoader.loadModifiedClass(MockClassLoader.java:180)在org.powermock.core.cl

  • 我是Mockito的新手,正在尝试模拟服务方法。但是,Mockito无法正确模拟函数。 以下是部分测试代码: 课程: 我期待返回一个非空列表。但是,它返回了一个空列表。有人能帮忙吗?

  • 我有一个Spring MVC应用程序。它有控制器、服务和Dao。我只想通过使用Mockito模拟DAO层来测试控制器和服务。 我的控制器类: 我的服务类: 我的测试类: 问题:通过自动连线控制器和服务,它可以很好地执行通话。然而,从服务中,DAO调用的是一个真正的DAO,而不是模拟的DAO。 > 在控制器中保留道并对控制器使用@InjectMock可以正常工作,但是我想在服务中保留道,并且只测试控

  • 我也是Mockito和PowerMockito的新手。我发现我无法使用纯Mockito测试静态方法,因此我需要使用PowerMockito(对吗?)。 我有一个非常简单的类,名为Validate,使用这个非常简单的方法 因此,我需要验证: 1) 当我在null message参数上调用该静态方法时,将调用IllegalArgumentException。2)当我在null object参数上调用该

  • 运行jUnit时的异常 我想测试这个类,下面是测试方法 运行junit会产生以下异常

  • 由于各种原因,我的单元测试环境无法访问启动ignite所需的环境。我不需要ignite来启动测试,我希望代码忽略对ignite的调用。开始()。我该怎么做? 我尝试过模拟点火,但当我尝试模拟start()方法时,它会抛出一个错误。 这会导致以下错误: 组织。莫基托。例外情况。误用。MissingMethodInvocationException:when()需要的参数必须是“模拟的方法调用”。例如