【问题标题】:Null Pointer Exception, when Writing Junit/Mockito Test cases at Controller class for Oauth, JSON response空指针异常,在控制器类中为 Oauth 编写 Junit/Mockito 测试用例时,JSON 响应
【发布时间】:2019-02-01 10:42:50
【问题描述】:

我对 Mockito 中的测试比较陌生,我正在尝试为控制器级别的测试编写一些测试用例,并且在运行测试用例时遇到空指针异常。我在控制器层注入模拟并模拟服务层方法。请告诉我,问题

控制器类:

@RestController
@RequestMapping(value="v1.0/authentication")
public class OauthTokenController {

    //Logging
    private static final Logger LOG = LoggerFactory.getLogger(OauthTokenController.class);

    @Autowired
    private SsasServiceImpl ssasService;

    @RequestMapping(value="/oauth/token", method=RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public TokenActivationResponse grantToken(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("grant_type") String grant_type){
        TokenActivationResponse tokenActivationResponse = new TokenActivationResponse();
        SecureString passwordSecured = new SecureString(password);
        try{
            tokenActivationResponse = ssasService.grantToken(username, passwordSecured, grant_type);
            if(tokenActivationResponse == null){
                throw new Exception();
            }
            LOG.info("Printing the response " + tokenActivationResponse);
        }catch(Exception e){
            LOG.error("Exception in oauth token granting controller", e);
        }
        return tokenActivationResponse;
    }
}

SSASServiceImpl:

public class SSASServiceImpl{
    public TokenActivationResponse grantToken(String username, SecureString password, String grant_type) throws IdvException {
        MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
        body.add(USERNAME, username);
        body.add(PASSWORD, (password != null) ? String.valueOf(password.getContent()) : null);
        body.add(GRANT_TYPE, grant_type);
        com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse tokenResponse = new com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse();
        TokenActivationResponse response = new TokenActivationResponse();
        tokenResponse = restProxy.sendAndReceiveToRestService(body, TOKEN, HttpMethod.POST, com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse.class);
        response = transformGrantTokenResp(tokenResponse);
        return response;
    }


    public TokenActivationResponse transformGrantTokenResp(com.idv.gateway.api.ssas.rest.client.model.TokenActivationResponse response) throws IdvException {
        if (response != null) {
            TokenActivationResponse resp = new TokenActivationResponse();
            resp.getData().getAttributes().setAccess_token(response.getAccess_token());
            resp.getData().getAttributes().setToken_type(response.getToken_type());
            resp.getData().getAttributes().setExpires_in(response.getExpires_in());
            resp.getData().getAttributes().setScope(response.getScope());
            return resp;
        } else {
            IdvError error = new IdvError();
            error.setTitle("Token Error");
            throw new IdvException(error);
        }
    }
}

测试类:

@RunWith(MockitoJUnitRunner.class)
public class OauthTokenControllerTest {

   String accessToken = "d6234595-812d-40fc-b519-2e3456543";
   Long expiresIn = 2905L;
   String userName = "abcd";
   String  password = "efghijk";
   String grant_type = "password";
   String  tokenType = "bearer";
   String  scope = "read write";

    @Mock
    SsasServiceImpl ssasService = new SsasServiceImpl();

    @InjectMocks
    OauthTokenController controller = new OauthTokenController();

    @Before
    public void setUp(){

    }

    TokenActivationResponse resp = new TokenActivationResponse();



    @Test
    public void testGrantToken() throws IdvException {
        resp.getData().getAttributes().setAccess_token(accessToken);
        resp.getData().getAttributes().setToken_type(tokenType);
        resp.getData().getAttributes().setExpires_in(expiresIn);
        resp.getData().getAttributes().setScope(scope);
        SecureString sec = new SecureString(password);
        Mockito.when(ssasService.grantToken(any(String.class),any(SecureString.class),any(String.class) )).thenReturn(resp);
        final TokenActivationResponse response = controller.grantToken(any(String.class),any(String.class),any(String.class));
        assertNotNull(response);
    }
}

例外:

Connected to the target VM, address: '127.0.0.1:60951', transport: 'socket'
16:21:38.387 [main] ERROR com.idv.gateway.controller.OauthTokenController - Exception in oauth token granting controller
java.lang.Exception: null
    at com.idv.gateway.controller.OauthTokenController.grantToken(OauthTokenController.java:33)
    at com.idv.gateway.controller.OauthTokenControllerTest.testGrantToken(OauthTokenControllerTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

java.lang.AssertionError
    at org.junit.Assert.fail(Assert.java:86)
    at org.junit.Assert.assertTrue(Assert.java:41)
    at org.junit.Assert.assertNotNull(Assert.java:712)
    at org.junit.Assert.assertNotNull(Assert.java:722)
    at com.idv.gateway.controller.OauthTokenControllerTest.testGrantToken(OauthTokenControllerTest.java:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Disconnected from the target VM, address: '127.0.0.1:60951', transport: 'socket'
[MockitoHint] OauthTokenControllerTest.testGrantToken (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at com.idv.gateway.controller.OauthTokenControllerTest.testGrantToken(OauthTokenControllerTest.java:60)
[MockitoHint]  ...args ok? -> at com.idv.gateway.controller.OauthTokenController.grantToken(OauthTokenController.java:31)


Process finished with exit code -1

【问题讨论】:

  • 你可以试试@Mock SsasServiceImpl ssasService;
  • when(ssasService.grantToken(..).thenReturn(..) 我强烈建议你阅读一些关于 Mockito 的教程
  • @dehasi 谢谢,但是我尝试了各种方法,我总是在控制器类这一行得到异常:tokenActivationResponse = ssasService.grantToken(username, passwordSecured, grant_type);。 “tokenActivationResponse”返回相同的 Null

标签: java spring-boot testing junit mockito


【解决方案1】:

我已经解决了这个问题:

解决方案和修复:

在我的 TestCase 代码中,我替换了下面的 any(String.class):

Mockito.when(ssasService.grantToken(any(String.class),any(SecureString.class),any(String.class))).thenReturn(resp); 最终 TokenActivationResponse 响应 = controller.grantToken(any(String.class),any(String.class),any(String.class));

与(anyString()):

Mockito.when(ssasService.grantToken(anyString(),any(SecureString.class),anyString())).thenReturn(resp); final TokenActivationResponse response =controller.grantToken(anyString(),any(String.class),anyString());

这些链接之一帮助:Mockito - Invalid use of argument matchers 此外,如果您在 mockito 中为一个参数使用参数匹配器,请确保对所有参数都使用。

【讨论】:

    猜你喜欢
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 2019-05-24
    • 2021-06-15
    • 1970-01-01
    相关资源
    最近更新 更多