无法模拟类,引发异常

时间:2019-08-04 11:02:00

标签: java unit-testing junit mockito powermock

需要帮助来了解我的单元测试出了什么问题     @测试     公共无效testDownloadSolutionFileAlreadyPresentInLocalRepo()引发异常{         字符串downloadUrl =“ https://artifactory.com/artifactory/com/test-artifact/1.0.0/test-artifact-1.0.0.zip”;         字符串路径=“ com / test-artifact / 1.0.0 /”;         PowerMockito.mockStatic(ApplicationContext.class);         ApplicationContext实例= PowerMockito.mock(ApplicationContext.class);         PowerMockito.when(ApplicationContext.getInstance())。thenReturn(instance);         PowerMockito.when(instance.getRepositoryDirectory())。thenReturn(“ \ repository”);

    SafeFile safeFile = PowerMockito.mock(SafeFile.class);
    PowerMockito.whenNew(SafeFile.class).withArguments(ApplicationContext.getInstance().getReportsDirectory()).thenReturn(safeFile);
    when(safeFile.getChild(Mockito.any())).thenReturn(safeFile);
    SafeFile result = subsystem.downloadSolution(downloadUrl, path);
    Assert.assertEquals(safeFile, result);
}

SC.class内部

    SafeFile downloadSolution(String downloadUrl, String path) throws Exception {
        try {
            String fileName = downloadUrl.substring(downloadUrl.lastIndexOf(SharedConstants.PATH_DELIMITER) + 1, downloadUrl.length());
            SafeFile rootRepoDir = new SafeFile(ApplicationContext.getInstance().getRepositoryDirectory());
            String pkgSolutionPath = "DownloadedSolutions" + SharedConstants.PATH_DELIMITER + path;
            SafeFile tempFile = rootRepoDir.getChild(pkgSolutionPath + fileName);
            if (tempFile.exists()) {
                return tempFile;
            } else {
some logic ...
return new_file;}

StackTrace:

java.lang.Exception
    at com.system.subsystems.solutioncentral.SC.downloadSolution(SC.java:1017)
    at com.system.subsystems.solutioncentral.SCTest.testDownloadSolutionFileAlreadyPresentInLocalRepo(SCTest.java:832)
    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.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
    at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:136)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

单元测试以空指针异常退出。 SafeFile rootRepoDir的值为空,我不知道为什么。我嘲笑了它,为什么它显示为null? 如果删除此行,则PowerMockito.whenNew(SafeFile.class).withAnyArguments()。thenReturn(file1); ,则rootRepoDir的值不为null

我已经在PrepareForTest中添加了SC.class,并与PockerMockRunner一起运行

2 个答案:

答案 0 :(得分:0)

您有:

new SafeFile(ApplicationContext.getInstance().getRepositoryDirectory());

您还可以在mockStatic类上使用ApplicationContext

PowerMockito.mockStatic(ApplicationContext.class);
ApplicationContext mockedApplicationContext = Mockito.mock(ApplicationContext.class);

但是,您不会对该类执行任何存根操作,因此,在调用ApplicationContext.getInstance()时,您将获得默认的返回值NULL。然后,您尝试致电NULL.getRepositoryDirectory()并因此致电NPE。

因此,请确保在致电SUT之前就将其设置好:

PowerMockito.when(ApplicationContext.getInstance()).thenReturn(appCtxStub);

答案 1 :(得分:0)

解决问题后,我尝试在另一堂课中重现该问题,
但是我只是设法确认withAnyArguments似乎无效。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Test.class)
public class Test {

    public class Value {
        final String content;

        public Value(String content) {
            this.content = content;
        }   
    }

    public class ValueBuilder {

        private String content;

        public ValueBuilder(String content) {
            this.content = content;
        }

        public Value build() {
            return new Value(content);
        }
    }

    public static class Utils {

        static Utils instance = new Utils();

        static Utils getInstance() {
            return instance;
        }

        public String getToken() {
            return null;
        }
    }

    @Test
    public void test() throws Exception {

        PowerMockito.mockStatic(Utils.class);
        Utils utils = Mockito.mock(Utils.class);
        Mockito.when(utils.getToken()).thenReturn("\\any");
        Mockito.when(Utils.getInstance()).thenReturn(utils);

        ValueBuilder builder = Mockito.mock(ValueBuilder.class);

        // working
        PowerMockito.whenNew(ValueBuilder.class).withArguments(Mockito.any(String.class)).thenReturn(builder);              

        // not working
        //PowerMockito.whenNew(ValueBuilder.class).withAnyArguments().thenReturn(builder);                                  

        // working
        //PowerMockito.whenNew(ValueBuilder.class).withArguments("\\any").thenReturn(builder);                              

        // working
        //PowerMockito.whenNew(ValueBuilder.class).withArguments(Utils.getInstance().getToken()).thenReturn(builder);       

        Mockito.when(builder.build()).thenReturn(new Value("real"));

        new ValueBuilder(Utils.getInstance().getToken()).build();
    }
}