莫基托。我试图模拟的依赖项是 NULL

Mockito. Dependency I am trying to mock is NULL

在我试图测试的 class 中,我有 @Resource 注释依赖项,我正在尝试编写一些测试并想注入该依赖项,我的问题是,在模拟依赖它的价值是 null

private SOAPService soapService;
private WebServiceContext webServiceContext = mock(WebServiceContextImpl.class);

@Before
public void setup(){
    soapService = new SOAPService(webServiceContext);
}

@Test
public void startUploadFileTest(){
    soapService.startUpload("text");
    ......
    /I omitted the remaining code, because I get the NullPointerException/
}

注意。我的测试 Class 被注释为 MockitoJUnitRunner.class

编辑 SoapService 实现

@WebService
public class SOAPService{

        private final static AtomicInteger id = new AtomicInteger();
        private WebServiceContext webServiceContext; 

        public SOAPService(WebServiceContext webServiceContext){
                this.webServiceContext = webServiceContext;
        }

        @Override
        public int startUpload(@WebParam String name) {
            String username = Authentication.getUsername(webServiceContext.getMessageContext());

            try {
                File file = new File(username + "/" + name);
                file.createNewFile();
            } catch (IOException e) {
                LOG.error(e.getMessage(), e);
                e.printStackTrace();
            }
            return id.getAndIncrement();
        }
}

java.lang.NullPointerException
    at org.example.SOAPService.startUpload(SOAPService.java:97)
    at org.example.services.SOAPServiceTest.startUploadFileTest(SOAPServiceTest.java:39)
    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.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    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:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:53)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    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:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

据我所知,您的 soapService 与模拟的 webServiceContext 没有任何联系。

如果您在 类 中使用依赖注入: 您应该使用 @InjectMocks 注释您的 SOAPService 字段,以便 Mockito 知道该做什么。如果您这样做,Mockito 将实例化您的 soapService 并将 Mocks 注入其中。无需手动调用构造函数。

如果您不在 类 中使用依赖注入: 您必须通过 setter 将您的 WebServiceContext 设置到您的 soapService 中,这不会神奇地发生。

您是否尝试像这样初始化您的 soapService:

@Before
public void setup(){
    soapService = new SOAPService();
    Mockito.initMocks(soapService);
}

编辑

使用新代码,您还必须模拟静态方法

Authentication.getUsername(...)

为此,您必须使用 PowerMockito。

在class之前添加声明注解@PrepareForTest like

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Authentication.class})
public class MyTest {
   ....
}

在准备测试期间模拟对 getUserName 的调用

@Before
public void setup(){
   soapService = new SOAPService(webServiceContext);
   PowerMockito.when(Authentication.getUsername(Mockito.any())).thenReturn("m‌​yVal‌​ue");
}