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
会最适合您的情况。我建议您从模拟对象中删除这些答案。这将导致您的测试失败,因为您没有预料到任何这些交互。
我在 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
会最适合您的情况。我建议您从模拟对象中删除这些答案。这将导致您的测试失败,因为您没有预料到任何这些交互。