Java Mockito.when()在模拟自动连线对象时工作不正常

Java Mockito.when()在模拟自动连线对象时工作不正常,java,junit,mockito,Java,Junit,Mockito,我有一个conrtoller类,在该类中,我将获得有关当前登录用户的详细信息。方法名为LoggedInUser()。该方法总体上运行良好,但我无法为特定方法生成单元测试用例 为了测试它,我使用Mockito,但是Mockito.when()工作不正常。 我把所有相关的问题都问了一遍,但都没能解决 以下是我到目前为止所做的 Controller.java @Service @Transactional Public class Controller implements s

我有一个conrtoller类,在该类中,我将获得有关当前登录用户的详细信息。方法名为
LoggedInUser()
。该方法总体上运行良好,但我无法为特定方法生成单元测试用例

为了测试它,我使用Mockito,但是
Mockito.when()
工作不正常。 我把所有相关的问题都问了一遍,但都没能解决

以下是我到目前为止所做的

Controller.java

    @Service
    @Transactional
    Public class Controller implements someInterface {

private LoggedInUser getUser(HttpServletRequest request) {
            principal = request.getUserPrincipal();
            Authentication tk = (Authentication) principal;
            //Authentication tk = (Authentication)(request.getUserPrincipal());
            LoggedInUser user = (LoggedInUser) tk.getPrincipal();
            return user;
        }
    @Service
    @Transactional
    Public class Controller implements someInterface {

    public LoggedInUser getUser() {
        LoggedInUser user = (LoggedInUser )SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return user;
    }
    @Mock
    private Principal principal;

    @Mock
    private SecurityContext securitycontext;

    @Mock
    private Authentication authentication;
     public void test() {
      LoggedInUser user = new LoggedInUser();
        Mockito.when(authentication.getPrincipal()).thenReturn(user);
        Mockito.when(securitycontext.getAuthentication()).thenReturn(authentication);
        SecurityContextHolder.setContext(securitycontext);
.......
.......
}
注释中的这一行是因为我在另一篇文章中读到它可能无法工作,因为“主体”再次被实例化。所以我试着绕过它,但效果不太好

Test.java

@Mock
    private HttpServletRequest httpServletRequest;

public void tes() {
        //httpServletRequest = Mockito.mock(HttpServletRequest.class);
        Principal principal= Mockito.mock(Principal.class);
        Mockito.when(httpServletRequest.getUserPrincipal()).thenReturn(principal);
.......
.......
}

调试时,我得到
request(HttpServletRequest的对象)
的值,因为它在控制器类中自动连接,但
principal
始终为空。
任何帮助都将不胜感激

您尚未注入模拟对象
httpServletRequest
。您需要将此模拟对象传递给您的
getUser
方法进行测试。

您尚未注入模拟对象
httpServletRequest
。您需要将此模拟对象传递给您的
getUser
方法进行测试。

您是否在此测试类上添加了
@RunWith(MockitoJUnitRunner.class)
?因为只有到那时,
@Mock
才会起作用。我假设您正在将mocked
HttpServletRequest
传递给
getUser()

您是否在这个测试类上添加了
@RunWith(MockitoJUnitRunner.class)
?因为只有到那时,
@Mock
才会起作用。我假设您正在将mock
HttpServletRequest
传递给
getUser()
我无法mock
HttpServletRequest
,因为它是
自动连线的,因此
请求。getUserPrincipal()
始终保持空值,因为它从不调用
mock()。
我用下面的方式替换了代码,它工作了

Controller.java

    @Service
    @Transactional
    Public class Controller implements someInterface {

private LoggedInUser getUser(HttpServletRequest request) {
            principal = request.getUserPrincipal();
            Authentication tk = (Authentication) principal;
            //Authentication tk = (Authentication)(request.getUserPrincipal());
            LoggedInUser user = (LoggedInUser) tk.getPrincipal();
            return user;
        }
    @Service
    @Transactional
    Public class Controller implements someInterface {

    public LoggedInUser getUser() {
        LoggedInUser user = (LoggedInUser )SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return user;
    }
    @Mock
    private Principal principal;

    @Mock
    private SecurityContext securitycontext;

    @Mock
    private Authentication authentication;
     public void test() {
      LoggedInUser user = new LoggedInUser();
        Mockito.when(authentication.getPrincipal()).thenReturn(user);
        Mockito.when(securitycontext.getAuthentication()).thenReturn(authentication);
        SecurityContextHolder.setContext(securitycontext);
.......
.......
}
Test.java

    @Service
    @Transactional
    Public class Controller implements someInterface {

private LoggedInUser getUser(HttpServletRequest request) {
            principal = request.getUserPrincipal();
            Authentication tk = (Authentication) principal;
            //Authentication tk = (Authentication)(request.getUserPrincipal());
            LoggedInUser user = (LoggedInUser) tk.getPrincipal();
            return user;
        }
    @Service
    @Transactional
    Public class Controller implements someInterface {

    public LoggedInUser getUser() {
        LoggedInUser user = (LoggedInUser )SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return user;
    }
    @Mock
    private Principal principal;

    @Mock
    private SecurityContext securitycontext;

    @Mock
    private Authentication authentication;
     public void test() {
      LoggedInUser user = new LoggedInUser();
        Mockito.when(authentication.getPrincipal()).thenReturn(user);
        Mockito.when(securitycontext.getAuthentication()).thenReturn(authentication);
        SecurityContextHolder.setContext(securitycontext);
.......
.......
}

我无法模拟
HttpServletRequest
,因为它是
自动连线的
,因此
请求。getUserPrincipal()
始终保持空值,因为它从不调用
mock()。当
方法时。 我用下面的方式替换了代码,它工作了

Controller.java

    @Service
    @Transactional
    Public class Controller implements someInterface {

private LoggedInUser getUser(HttpServletRequest request) {
            principal = request.getUserPrincipal();
            Authentication tk = (Authentication) principal;
            //Authentication tk = (Authentication)(request.getUserPrincipal());
            LoggedInUser user = (LoggedInUser) tk.getPrincipal();
            return user;
        }
    @Service
    @Transactional
    Public class Controller implements someInterface {

    public LoggedInUser getUser() {
        LoggedInUser user = (LoggedInUser )SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return user;
    }
    @Mock
    private Principal principal;

    @Mock
    private SecurityContext securitycontext;

    @Mock
    private Authentication authentication;
     public void test() {
      LoggedInUser user = new LoggedInUser();
        Mockito.when(authentication.getPrincipal()).thenReturn(user);
        Mockito.when(securitycontext.getAuthentication()).thenReturn(authentication);
        SecurityContextHolder.setContext(securitycontext);
.......
.......
}
Test.java

    @Service
    @Transactional
    Public class Controller implements someInterface {

private LoggedInUser getUser(HttpServletRequest request) {
            principal = request.getUserPrincipal();
            Authentication tk = (Authentication) principal;
            //Authentication tk = (Authentication)(request.getUserPrincipal());
            LoggedInUser user = (LoggedInUser) tk.getPrincipal();
            return user;
        }
    @Service
    @Transactional
    Public class Controller implements someInterface {

    public LoggedInUser getUser() {
        LoggedInUser user = (LoggedInUser )SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return user;
    }
    @Mock
    private Principal principal;

    @Mock
    private SecurityContext securitycontext;

    @Mock
    private Authentication authentication;
     public void test() {
      LoggedInUser user = new LoggedInUser();
        Mockito.when(authentication.getPrincipal()).thenReturn(user);
        Mockito.when(securitycontext.getAuthentication()).thenReturn(authentication);
        SecurityContextHolder.setContext(securitycontext);
.......
.......
}


取消注释
tes()
如果必须模拟的引用未分配模拟值,则模拟中的1行无效。您应该显示被测试方法的代码。请提供一个。@ppasler已经尝试过了…不起作用!!取消注释
tes()
如果必须模拟的引用未分配模拟值,则模拟中的1行无效。您应该显示被测试方法的代码。请提供一个。@ppasler已经尝试过了…不起作用!!我该怎么做呢?如果你的方法不是私有的,你可以在模仿它之后调用
getUser(httpServletRequest)
httpServletRequest=Mockito.mock(httpServletRequest.class)。您需要查看将其传递到servlet的位置在调试时,我正在获取
请求(HttpServletRequest的对象)
的值,因为它在控制器类中是自动连接的,但
主体
始终为空。我该如何做呢?如果您的方法不是私有的,您可以调用
getUser(HttpServletRequest)
模拟后
httpServletRequest=Mockito.mock(httpServletRequest.class)。您需要查看将其传递到servlet的位置在调试时,我正在获取
请求(HttpServletRequest的对象)
的值,因为它在控制器类中自动连接,但
主体
始终为空。否。我添加了“MockitoAnnotations.initMocks(this)”是的,这也将初始化您的mock。您能提供完整的示例吗?对不起,我不能。但我可以看出,在'Mockito.when()'之后,将调用另一个函数;它调用“LoggedInUser()”。从您对另一个答案的评论可以很清楚地看出,HttpServletRequest没有被模仿。由于它是自动连接到您的控制器,调查周围的方式应该如何模拟。如果我发现了什么,我会更新。否。我添加了“MockitoAnnotations.initMocks(this)”是的,这也将初始化您的mock。您能提供完整的示例吗?对不起,我不能。但我可以看出,在'Mockito.when()'之后,将调用另一个函数;它调用“LoggedInUser()”。从您对另一个答案的评论可以很清楚地看出,HttpServletRequest没有被模仿。由于它是自动连接到您的控制器,调查周围的方式应该如何模拟。如果我发现了什么,我会更新。