Mockito RETURNS_SMART_NULLS 回答奇怪的行为

Mockito RETURNS_SMART_NULLS answer weird behavior

我在 Mockito 1.9.5 中使用注释 @Mock(answer=Answers.RETURNS_SMART_NULL) 以便在发生某些意外的模拟调用时获得一些 SmartNullPointerException。

不幸的是,测试通过了,即使没有模拟至少一个重要的调用。 要清楚:我的意思是不是自己找到我缺少的东西但是失败测试 因为 我没有模拟这些方法。我不想使用 Mockito.verifyNoMoreInteractions(...)

我的测试:

@RunWith(MockitoJUnitRunner.class)
public class ContextServiceImplTest {

    @Mock(answer = Answers.RETURNS_SMART_NULLS)
    private IAccountDAO accountDaoMock; 
    @Mock(answer = Answers.RETURNS_SMART_NULLS)
    private IRuleService ruleServiceMock;
    @Mock(answer = Answers.RETURNS_SMART_NULLS)
    private ISensorDAO sensorDAOMock;

    private ContextServiceImpl contextService;

    @Before
    public void before() {
        contextService = new ContextServiceImpl(accountDaoMock, ruleServiceMock, sensorDAOMock);
    }

    @Test
    public void fillSensor() throws Exception {
        // given
        String givenSensorId = "123"
        final EventDTO givenEvent = new EventDTO();
        givenEvent.setSensorId(givenSensorId)

        // when
        final Context context = contextService.getContext(givenEvent);

        // then (should fail and throw explicit exception

    }

待测代码:

public class ContextServiceImpl {
    ...

    public Context getContext(final EventDTO event) throws Exception {
        final String sMethodName = "getContext";
        final String sensorId = event.getSensorId();
        Context context = new Context();

        try {
            final Sensor sensor = sensorDAO.findById(sensorId);
            context.setSensor(sensor);
            return context;
        } catch (final NoResultException nre) {
            throw new BusinessException(ValidationCode.UNSUPPORTED_VALUE, "sensorId");
        } catch (final PersistenceException pe) {
            throw new TechnicalException(TechnicalCode.DATABASE_ACCESS_PROBLEM);
    }
}

感谢您的评论/建议/解释。

您需要在 null 对象 sensor 上调用方法才能使测试失败。

您似乎从未使用过 null 对象 sensor。 这意味着你不会得到任何NullPointerExceptions(聪明与否)

你可以做一个

AssertEquals(context.getSensor().someMethod(), expectedResult);

或者只是一个

context.getSensor().someMethod();

获取异常。 但是

AssertNotNull(context.getSensor());

不足以获得 SmartNullPointerException

您的测试仍然会通过,因为您没有使用任何这些模拟调用的结果调用任何东西。

RETURNS_SMART_NULLS 仅在您尝试取消引用 SmartNull 时抛出 SmartNullPointerException。本质上,它告诉您您正在以更友好的方式取消引用 null 值,而您并没有使用当前代码这样做。

首先 - 你新建了一个 Context。除非你陷入线程问题的杂草中,否则它永远不会回来 null

接下来 - 您将传递一个新的 EventDTO。出于与上述相同的原因,那也不会是 null

sensor的结果可能null,但这并不重要——你只是将它传递给context 而不对其调用任何逻辑。

我不相信 RETURNS_SMART_NULLS 会最适合您的情况。我建议您从模拟对象中删除这些答案。这将导致您的测试失败,因为您没有预料到任何这些交互。