在Controller类为Oauth,JSON响应编写Junit / Mockito测试用例时,出现空指针异常

时间:2018-08-26 20:35:29

标签: java spring-boot testing junit mockito

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

控制器类:

@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

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题:

解决方案和修复:

在我的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 另外,如果您在模仿中将参数匹配器用于一个参数,请确保对所有参数都使用。