即使args是正确的,org.mockito.Mockito.mock也无效

时间:2016-08-28 11:51:46

标签: java spring unit-testing spring-boot

我正在尝试对我继承的springboot应用程序进行单元测试。

以下是我初始化单元测试的模拟部分的方法:

public class ValidationServiceTest {

    private Logger LOG = null;
    private final Long INVALID_ID = -1L;
    private Long custId = 4;
    private String username = "foo";

    cRepository repo;
    Customer customer = null;
    ValidationService  = null;

    @Before
    public void setUp() {

        validationService = new ValidationService();
        customer = new Customer();
        customer.setUsername(username);
        customer.setCustId(custId);

        repo = mock(cRepository.class);
        when(repo.searchByUsername(any(String.class))).thenReturn(customer);

        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void getCustIdTest() {
        Long result = .getCustId(username);
    }
}

然后在生产部分,我有这行代码:

    public Long getCustId(String username) {

    // Here it breaks
    Customer customer = repo.searchByUsername(username);
    return customer.getCustId;
}

我知道通过检查日志将正确的值(用户名,密码,id)传递给代码。问题是上面的行返回一个NullPointerException。

这显然是错的吗?我希望它能返回一个用户名为“foo”的客户,但它没有。

异常的堆栈跟踪

  

显示java.lang.NullPointerException       在com.mypkg.db.ValidationService.getCustId(ValidationService.java:27)       在com.mypkg.db.ValidationServiceTest.getCustIdTest(ValidationServiceTest.java:77)       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)       在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50)       在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)       在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)       在org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)       在org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)       在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)       在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)       在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)       在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)       在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)       在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)       在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)       在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)       在org.junit.runners.ParentRunner.run(ParentRunner.java:363)       在org.junit.runner.JUnitCore.run(JUnitCore.java:137)       在com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)       at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)       在com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)       在com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)       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)       在com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

2 个答案:

答案 0 :(得分:1)

在Spring中可能是您​​的autoWired存储库是一个接口

public interface cRepo  extends MongoRepository<X ,String>{  

无法嘲笑

cRepo = mock(cRepository.class);

答案 1 :(得分:1)

考虑到代码的某些部分缺失,最可能的解释是,您嘲笑cRepository,但不要将其注入ValidationService,这可以解释所有发生在这里。

想象一下,你正在嘲笑方向盘来测试汽车 - 但是你没有把它放进你正在测试的汽车中,当然,当它试图进入方向盘时会抛出一个Nullpointer异常,因为它不存在,只是躺在其他地方,这根本不能帮助你进行测试......

通常情况下,您可以简单地写出类似的东西......

@RunWith(MockitoJUnitRunner.class)
public class ValidationServiceTest {

   @Mock
   private CRepository cRepository; // the runner, see above, will automatically mock this now

   @InjectMocks
   private ValidationService validationService;  // The runner will create this and inject all the mocks into it

   @Test
   public void myTest() {
      Customer customer = new Customer();
      customer.setUsername("foo");
      customer.setCustId(4);
      when(cRepository.searchByUsername(any(String.class))).thenReturn(customer);

      Long result = validationService.getCustId(username);
      assert(result.equals(4));
}

这样,Mockito将自动创建模拟对象并将其注入validationService对象。

哦,请大家上课!