【问题标题】:Mockito test case not covering internal function callMockito 测试用例不包括内部函数调用
【发布时间】:2017-01-27 10:41:50
【问题描述】:

您好,我正在尝试使用 JUNIT + MOCKITO 开发测试用例,并因此面临一个问题..

这是我正在尝试测试的方法

    public Response create(Request request)
      throws SQLException, InvalidSecretKeyException, UnsupportedEncodingException, GeneralSecurityException,
      InvalidParametersException, InvalidAuthKeyException, ConstraintViolationExceptions, InvalidKeyHashException, InvalidApplicationKeyException {
    User user = userService.validateAndReturnUserBy(request.headers("AuthKey"));

    ApplicationWrapper applicationWrapper = JsonUtil.deSerialize(request.body(), ApplicationWrapper.class);

    //System.out.println(applicationWrapper.getSecretKey());

    Application application=new Application();
    application.setKey(getApplicationKey(user.getUserName(), applicationWrapper.getType().getName(), applicationWrapper.getName()));
    System.out.println("GEN KEY ::::" + getApplicationKey(user.getUserName(), applicationWrapper.getType().getName(), applicationWrapper.getName()));
    application.setName(applicationWrapper.getName());
    application.setPackageName(applicationWrapper.getPackageName());
    application.setSendOTPInResponse(applicationWrapper.getSendOTPInResponse());
    application.setType(applicationWrapper.getType());

    application.setSignature(applicationWrapper.getSignature());
    application.setCreatedAt(getMysqlTimeStamp());
    application.setCreatedBy(user);
    application.setUpdatedBy(user.getId());
    application.setOtpExpiry(applicationWrapper.getOtpExpiry());
    application.setOtpLength(applicationWrapper.getOtpLength());
    application.setRandomNumber(tempRandomNumber);

    validator.validate(application);
    applicationRepository.create(application);
    System.out.println(applicationWrapper);

    Application thisApp =applicationRepository.getBy(application);
     List<String> secretKeys = applicationWrapper.getSecretKey();
     System.out.println("Application Service ::: \n"+thisApp);
     insertApplicationSecretKeys(secretKeys,thisApp);
    Map<String, String> responseBody = new HashMap<>();
    responseBody.put("application_key", application.getKey());
    responseBody.put("message", "Application created Successfully");

    return new Response("success", responseBody);
}

这是我的 Mockito + JUnit 测试用例

   @Test
  public void shouldCreate() throws SQLException, ResourceNotFoundException, InvalidSecretKeyException,
          UnsupportedEncodingException, GeneralSecurityException, InvalidAuthKeyException, InvalidParametersException, ConstraintViolationExceptions, InvalidKeyHashException, SendGridException, InvalidApplicationKeyException {

    when(request.headers("AuthKey")).thenReturn("some-auth-key");
    when(userService.validateAndReturnUserBy("some-auth-key")).thenReturn(user);
    when(request.body()).thenReturn(JsonUtil.toJson(make(a(ApplicationWrapperMaker.ApplicationWrapper))));
    when(applicationTypeRepository.getByName("WEB")).thenReturn(make(a(ApplicationTypeMaker.ApplicationType)));
    when(userRepository.getByAuthKey("some-auth-key")).thenReturn(user);

    //doNothing().when(appService).insertApplicationSecretKeys(make(a(ApplicationSecretKeyMaker.ApplicationSecretKey)), make(a(Application)));
    //doThrow(new RuntimeException("App created")).when(appService).insertApplicationSecretKeys(make(a(ApplicationSecretKeyMaker.ApplicationSecretKey)), make(a(Application)));

    Response response = applicationService.create(request);

    assertEquals("success", response.getStatus());
    assertNotNull(response.getBody());
  }

insertApplicationSecretKeys(secretKeys,thisApp); 正在被调用.. 由于 Created 应用程序对象只是一个模拟对象,因此此方法返回 null 并且 NullPointer 异常出现在这一行。

this app variable is coming NULL.

请帮忙。

编辑:这是堆栈跟踪和输出

  java.lang.NullPointerException
    at com.sendotp.service.ApplicationService.insertApplicationSecretKeys(ApplicationService.java:297)
    at com.sendotp.service.ApplicationService.create(ApplicationService.java:92)
    at com.sendotp.service.ApplicationServiceTest.shouldCreate(ApplicationServiceTest.java:162)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    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.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    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.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)

输出 ::

    GEN KEY ::::AhLDuwI4x34cP6-pr3WJSKoHZ7ltat13CdAcWlkZ8DHyiIk9b8-606JJ9ZPPPbTRWdnU7bPQYp4jphpdfqFoOwHs0uEc0ewE2-MHe8Yyu0XxZZQ7nw7itYVTXNFPp-a2NFP8AZ89QIznIzGstVWyO7eL7DS_qmam8BUF5XHN-VA=
ApplicationWrapper{name='someApplicationName', type=com.sendotp.model.ApplicationType@57f791c6, packageName='some.package.name', otpExpiry=86400, senderId='somesenderId', otpLength=6, requestPerIp=100, key='null', createdBy=null, updatedBy=0, createdAt=null, updatedAt=null, randomNumber='null', secretKey=[121212, 32234324], signature='some-signature,#OTP', sendOTPInResponse=0}
Application Service ::: 
null

【问题讨论】:

  • 你必须对被测对象使用 spy 并告诉 insertApplicationSecretKeys 什么都不做
  • 请检查测试用例中注释的 2 行代码。我说的对吗
  • 但是调用create方法时会出现问题
  • 那你就不清楚了。您写道“insertApplicationSecretKeys(secretKeys,thisApp); 被调用时存在问题”。问题是在您调用该方法还是在您调用 create 时发生的?堆栈跟踪会有所帮助。顺便说一句,这个问题写得很糟糕。
  • 模拟 applicationRepository 并在调用 getBy 时使其返回模拟。

标签: java unit-testing junit mockito


【解决方案1】:

您的方法create 做得太多了。

特别是实例化Application 对象应该在方法之外完成。提供业务逻辑的其他类的对象创建不应在使用此依赖项的类中进行。 应该应用依赖倒置

最简单的方法是将Application 对象作为参数传递给方法(然后将其重命名为configure)。在这种情况下,您可以将其替换为可以验证预期方法调用的模拟。

【讨论】:

    猜你喜欢
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2019-08-18
    相关资源
    最近更新 更多