java 如何在使用Mockito时修复JUnit测试类中的空指针异常?[副本]

cgh8pdjw  于 2023-06-04  发布在  Java
关注(0)|答案(2)|浏览(407)

此问题已在此处有答案

Why are my mocked methods not called when executing a unit test?(1个答案)
2天前关闭。
我得到空指针异常,而测试。这是测试类。

@SpringBootTest
public class RunSummaryServiceImplTest {

    @Spy   //Tried @Mock too
    private RunSummaryRepository runSummaryRepository;

    /** The file repository. */
    @Spy
    private FileRepository fileRepository;

    @InjectMocks
    RunSummaryServiceImpl runSummaryServiceImpl;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void TestprocessCustomerRunSummaries() {

        final RunSummaryServiceImpl runSummaryServiceImpl = new RunSummaryServiceImpl();
        final Collection<RunSummary> runs = new ArrayList<>();
        runs.add(new RunSummary("customer1", 1, Timestamp.valueOf("2023-05-30 10:00:00")));
        runs.add(new RunSummary("customer2", 2, Timestamp.valueOf("2023-05-30 11:00:00")));
        runs.add(new RunSummary("customer3", 3, Timestamp.valueOf("2023-05-30 12:00:00")));

        runSummaryServiceImpl.processCustomerRunSummaries(runs);  //NULL POINTER EXCEPTION HERE
    }
}

我也试着用@Spy代替@Mock,我也试着用@ExtendWith改变@SpringBootTest,仍然得到同样的问题。
我也不能使用when.thenReturn(),因为方法processCustomerRunSummaries()是无效的。
下面是ServiceImpl类

@Service
    public class RunSummaryServiceImpl implements RunSummaryService {

    /** LOGGER. */
    private static final Logger LOGGER = LogManager.getLogger(RunSummaryServiceImpl.class.getName());

    /** RunSummaryRepository reference. */
    @Autowired
    private RunSummaryRepository runSummaryRepository;

    /** The file repository. */
    @Autowired
    private FileRepository fileRepository;

    
    @Override
    public void processCustomerRunSummaries(final Collection<RunSummary> runs) {
        LOGGER.debug("Customer RunSummary list size : {}", runs.size());
        final long start = System.currentTimeMillis();
        for (final RunSummary run : runs) {
    // Get RunSummaryEntity for each group. Create/update RunSummaryEntity statics for    each group.
        processCustomerRunSummary(run);
        }
    LOGGER.info("All {} Customer Run Summaries processing finished in {} milliseconds.", runs.size(),
            System.currentTimeMillis() - start);
    }

    
    @Override
    public void processCustomerRunSummary(final RunSummary run) {
        LOGGER.debug("Processing Customer Run Summary : {}", run);
        final String customerId = run.getCustomerId();
        final Integer solutionNumber = run.getSolutionNumber();
        final Timestamp downloadDatetime = run.getDownloadDatetime();

        try {
    //check if RunSummary is present in RunSummaryEntity.if not,create a RunSummaryEntity.If present     then
            // append its statistics.
            final RunSummaryEntity runEntityDb = runSummaryRepository
     .findByCustomerIdAndSolutionNumberAndDownloadDatetime(customerId, solutionNumber,downloadDatetime);

            if (null == runEntityDb) {
            createCustomerRunSummary(run, customerId, solutionNumber, downloadDatetime);
            } else {
            // runEntityDb exist in DB so update it with latest Statistics
        updateCustomerRunSummary(run, customerId, solutionNumber, downloadDatetime, runEntityDb);
            }
        } catch (final DataAccessException daException) {
        // just catch and log DataAccessException so that next RunSummaries should be processed.
    LOGGER.error("DataAccessException while processing customer RunSummary: {} , error: {}", run,
                daException);
        }
    }

同时添加下面的堆栈跟踪

java.lang.NullPointerException
    at     com.oversighttech.ocr.service.impl.RunSummaryServiceImpl.processCustomerRunSummary(RunSummaryServiceImpl.java:74)
    at com.oversighttech.ocr.service.impl.RunSummaryServiceImpl.processCustomerRunSummaries(RunSummaryServiceImpl.java:52)
    at com.oversighttech.ocr.service.impl.RunSummaryServiceImplTest.TestprocessCustomerRunSummaries(RunSummaryServiceImplTest.java:53)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    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.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)
ovfsdjhp

ovfsdjhp1#

您通过在测试中创建服务的新示例来使Mock无效。
移除

final RunSummaryServiceImpl runSummaryServiceImpl = new RunSummaryServiceImpl();

由于您的测试类已经有一个名为runSummaryServiceImpl的成员变量,该变量已注入了模拟,因此您的测试应该简单地如下所示:

@Test
public void TestprocessCustomerRunSummaries() {
    final Collection<RunSummary> runs = new ArrayList<>();
    runs.add(new RunSummary("customer1", 1, Timestamp.valueOf("2023-05-30 10:00:00")));
    runs.add(new RunSummary("customer2", 2, Timestamp.valueOf("2023-05-30 11:00:00")));
    runs.add(new RunSummary("customer3", 3, Timestamp.valueOf("2023-05-30 12:00:00")));

    // This is created as a mock at the class level
    runSummaryServiceImpl.processCustomerRunSummaries(runs);
}
p1iqtdky

p1iqtdky2#


我想你可以用这个例子:

when(myMock.doSomething()).thenThrow(new MyException());

或者,您可以使用以下内容注解测试:

@Test(expected=MyException.class)

相关问题