JUNIT问题,Spring测试-需要但未调用

bogh5gae  于 2023-02-12  发布在  Spring
关注(0)|答案(1)|浏览(134)

我不断得到这个错误消息,它dosent对我有意义我需要一些帮助来理解发生了什么我刚刚开始我的旅程在测试和我开始尝试测试我的一些实现的方法在我的应用程序中我决定从下面这个方法开始:

@Service
@Slf4j
public class LoginService {

    AuthenticationManager authenticationManager;
    JwtService jwtService;
    @Autowired
    LoginService(AuthenticationManager authenticationManager, JwtService jwtService){
        this.jwtService = jwtService;
        this.authenticationManager = authenticationManager;
    }

    public void logInUser(String username, String password, HttpServletResponse response){
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username,password);
        try{
            Authentication authUser = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
            String accessToken = jwtService.createAccessJwtToken(username);
            String refreshToken = jwtService.createRefreshJwtToken(username);
            Map<String, String> tokens = new HashMap<>();
            tokens.put("accessToken",accessToken);
            tokens.put("refreshToken",refreshToken);
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getWriter(),tokens);
        }catch (Exception e){
            throw new BadCredentialsException(e.getMessage());
        }
    }
}

我试着测试,但我有一个问题,我不明白我应该做什么,我尝试了一切,但似乎我做错了什么这里是测试代码,下面是问题:

@ExtendWith(MockitoExtension.class)
class LoginServiceTest {

    @Mock
    AuthenticationManager authenticationManager;
    @Mock
    JwtService jwtService;
    @Mock
    HttpServletResponse httpServletResponse;
    @Mock
    PrintWriter printWriter;
    @Mock
    Authentication authUser;
    @Mock
    ObjectMapper objectMapper;
    LoginService loginService;

    @BeforeEach
    void setUp() {
        this.loginService = new LoginService(authenticationManager,jwtService);
    }

    @Test
    void logInUser() throws Exception{
        String email = "test@test.com";
        String password = "test1234";
        Map<String,String> expectedTokens = new HashMap<>();
        String expectedCreatedAccessToken = "accessToken";
        String expectedCreatedRefreshToken = "refreshToken";
        expectedTokens.put("accessToken",expectedCreatedAccessToken);
        expectedTokens.put("refreshToken",expectedCreatedRefreshToken);
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(email,password);

        when(authenticationManager.authenticate(authToken)).thenReturn(authUser);
        when(jwtService.createAccessJwtToken(email)).thenReturn(expectedTokens.get("accessToken"));
        when(jwtService.createRefreshJwtToken(email)).thenReturn(expectedTokens.get("refreshToken"));
        when(httpServletResponse.getWriter()).thenReturn(printWriter);
        doNothing().when(objectMapper).writeValue(printWriter, expectedTokens);

        this.loginService.logInUser(email,password,httpServletResponse);

        verify(authenticationManager).authenticate(authToken);
        verify(httpServletResponse).getWriter();
        verify(jwtService).createAccessJwtToken(email);
        verify(jwtService).createRefreshJwtToken(email);
        verify(objectMapper).writeValue(printWriter,expectedTokens);
    }
}

错误:
想要但没有援引:写入值(打印写入器,{“访问令牌”=“访问令牌”,“刷新令牌”=“刷新令牌”});'

  • 〉at com.project.requests.login.service.登录服务测试.登录用户(LoginServiceTest. java:67)实际上,与这个模拟没有任何交互。
    我尝试了几乎所有的方法来处理doNothing().when(objectMapper).writeValue(printWriter, expectedTokens);,包括删除它、添加一些不同的参数或使用mockito的参数依赖项,但似乎没有什么可以解决我的错误
db2dz4w8

db2dz4w81#

为了使用模拟对象,服务代码必须使用依赖项注入,而不是使用构造函数创建ObjectMapper本身。
因此,为了让代码正常工作,您需要像这样注入ObjectMapper:

@Service
@Slf4j
public class LoginService {

    AuthenticationManager authenticationManager;
    JwtService jwtService;
    ObjectMapper objectMapper;
    @Autowired
    LoginService(AuthenticationManager authenticationManager, JwtService jwtService, ObjectMapper objectMapper){
    this.jwtService = jwtService;
    this.authenticationManager = authenticationManager;
    }
    ...
}

根据您的配置,您可能已经定义了ObjectMapper bean。如果没有,您需要定义一个配置类,该配置类将注册ObjectMapper bean,如下所示:

@Configuration
public class MapperConfiguration {
    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
   }
}

然后,您将能够在测试中注入一个模拟的ObjectMapper,如下所示:

@ExtendWith(MockitoExtension.class)
class LoginServiceTest {

    @Mock
    AuthenticationManager authenticationManager;
    @Mock
    JwtService jwtService;
    @Mock
    HttpServletResponse httpServletResponse;
    @Mock
    PrintWriter printWriter;
    @Mock
    Authentication authUser;
    @Mock
    ObjectMapper objectMapper;
    LoginService loginService;

    @BeforeEach
    void setUp() {
        this.loginService = new LoginService(authenticationManager,jwtService, objectMapper);
    }
    // @Test ...
}

然后,您模拟的ObjectMapper将被正确地注入,并按您所期望的那样被调用。
顺便说一句,您可以使用@InjectMocks注解创建具有模拟依赖项的服务,而不是在@BeforeEach方法中手动创建。

相关问题