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

@WithUserDetails失败,因为找不到用户名

窦凯定
2023-03-14

我正在尝试对我的AuthController.java进行测试,但是它总是说找不到用户名而失败。我已经将这个问题缩小到UserService.java中检查是否找到User==null的行。

这里是我的AuthControlllerTests.java

package dev.tdwl.controller;

import dev.tdwl.repository.CategoryListsRepository;
import dev.tdwl.repository.UserRepository;
import dev.tdwl.security.jwt.JwtUtils;
import dev.tdwl.services.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest(classes = {AuthController.class, UserService.class})
@AutoConfigureMockMvc
public class AuthControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private PasswordEncoder encoder;

    @MockBean
    private JwtUtils jwtUtils;

    @MockBean
    private AuthenticationManager authenticationManager;

    @MockBean
    private CategoryListsRepository categoryRepo;

    @MockBean
    private UserRepository userRepository;

    @Test
    @WithUserDetails(value = "testuser", userDetailsServiceBeanName = "userService")
    void testAuthenticationCheckValid() {
        try {
            mockMvc.perform(get("/auth/check")).andExpect(status().isOk()).andDo(print());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

还有我的AuthController。java

package dev.tdwl.controller;


import com.mongodb.MongoException;
import dev.tdwl.model.AuthenticationRequest;
import dev.tdwl.model.CategoryLists;
import dev.tdwl.model.JwtResponse;
import dev.tdwl.model.User;
import dev.tdwl.repository.CategoryListsRepository;
import dev.tdwl.repository.UserRepository;
import dev.tdwl.security.jwt.JwtUtils;
import dev.tdwl.services.UserDetailsImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;

@RestController
public class AuthController {

    private CategoryListsRepository categoryRepo;
    private UserRepository userRepo;
    private AuthenticationManager authenticationManager;
    private PasswordEncoder encoder;
    private JwtUtils jwtUtils;

    @Autowired
    public AuthController(UserRepository repository, AuthenticationManager authenticationManager, PasswordEncoder encoder, JwtUtils jwtUtils, CategoryListsRepository categoryRepo) {
        this.authenticationManager = authenticationManager;
        this.userRepo = repository;
        this.encoder = encoder;
        this.jwtUtils = jwtUtils;
        this.categoryRepo = categoryRepo;
    }

    @GetMapping("/auth/check")
    public ResponseEntity<?> verifyLogin() {
        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (userDetails.getId() == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }

        return ResponseEntity.ok(userDetails);
    }

    @PostMapping("/auth/login")
    public ResponseEntity<?> login(@RequestBody AuthenticationRequest authenticationRequest) {
        Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authenticationRequest.getEmail(), authenticationRequest.getPassword()));
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = jwtUtils.generateJwtToken(authentication);

        UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
        return ResponseEntity.ok(new JwtResponse(jwt, user.getUsername(), user.getId()));
    }

    @PostMapping("/auth/signup")
    public ResponseEntity<?> authenticateClient(@RequestBody AuthenticationRequest authenticationRequest) {
        String email = authenticationRequest.getEmail();
        String password = authenticationRequest.getPassword();

        User newUser = new User(email, encoder.encode(password));

        try {
            userRepo.save(newUser);
            CategoryLists newList = new CategoryLists(newUser.getId(), Collections.emptyList());
            categoryRepo.save(newList);
        } catch (DuplicateKeyException | MongoException e) {
            return ResponseEntity.status(HttpStatus.CONFLICT).build();
        }

        return ResponseEntity.ok("User registered successfully!");
    }
}

而我的用户ervice.java

package dev.tdwl.services;

import dev.tdwl.model.User;
import dev.tdwl.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UserService implements UserDetailsService {

    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User foundUser = userRepository.findUserByEmail(username);
        if (foundUser == null) throw new UsernameNotFoundException("User not found.");

        return UserDetailsImpl.build(foundUser);
    }
}

失败的行是在UserService.java中,它试图找到UserByEmail,因为userRepository被嘲笑了,它只是返回null并抛出username not search异常。如果我删除了Mock,那么我的测试失败了,因为它找不到AuthController中构造函数所需的UserRepository bean

有没有关于如何正确操作的想法?

共有1个答案

洪经义
2023-03-14

只需在这行中声明Mockbean for UserRepository:

@MockBean
private UserRepository userRepository;

这行不通。您需要在mockMvc之前添加以下代码。执行()

Mockito.when(userRepository.findUserByEmail(Mockito.anyString)).thenReturn(new User());

这将模拟findUserByEmail方法,并且不会返回null。

 类似资料:
  • 我的Ajax调用没有执行web方法,正在返回状态代码“302找到”。检查跟踪表明,该方法实际上是作为“选项”发送的?? 当web方法在aspx文件中时,这一切都在工作。当我把代码转换成UserControl时,我不得不把它移动到asmx。 Ajax调用: PLService中的Web方法 请求: 主持人:坦普里。org用户代理:Mozilla/5.0(Windows NT 6.1;WOW64;rv

  • 我在运行时开始出现此错误。 错误:无法解析配置的所有文件“:app:debugCompileClasspath”。 找不到play-services-basement.aar(com.google.android.gms:play-services-地下室:15.0.1)。在以下位置搜索:https://jcenter.bintray.com/com/google/android/gms/play

  • 当我点击“编辑”时,我收到此错误: 下面是< code>UsersController: 完整跟踪如下:

  • 即使其中一个软断言失败,测试也会继续。但是在我的例子中,我的测试在软断言失败后停止,因为找不到下一个测试元素。 这可以正常工作,但如果我设置: 我收到以下错误消息: 组织。openqa。硒。无接触元素异常。第二个软断言!!! 测试停止。 环境:Selenium 3.5 geckodriver Mozilla 56.0.1。

  • 我正在用网页包装我的羔羊。我正在用CDK部署它们。 然而,当通过ApiGateway测试它们时,我得到了这个: Lambda执行失败,状态200由于客户函数错误:错误:找不到模块'apollo-server-lambda'。 这是我的Webpack配置: 执行输出文件,如

  • 无法同步分级。 错误:找不到com.android.tools.build:gradle:1.0.0。在以下位置搜索:文件:/e:/installed/androidsdk/gradle/m2repository/com/android/tools/build/gradle/1.0.0/gradle-1.0.0.pom文件:/e:/installed/androidsdk/gradle/m2rep