所以我开始为Java-Spring项目编写测试 .
我使用的是JUnit和Mockito . 据说,当我使用when()... thenReturn()选项时,我可以模拟服务,而不需要模拟它们 . 所以我想做的是,设置:
when(classIwantToTest.object.get().methodWhichReturnsAList(input))thenReturn(ListcreatedInsideTheTestClass)
但无论我在哪个when子句中,我总是得到一个NullpointerException,当然这是有意义的,因为输入是null .
当我尝试从对象模拟另一个方法时:
when(object.method()).thenReturn(true)
在那里我也得到一个Nullpointer,因为该方法需要一个未设置的变量 .
但我想使用when().. thenReturn()来绕过创建这个变量等等 . 我只是想确保,如果任何类调用此方法,那么无论如何,只返回true或上面的列表 .
这是我身边的一个基本误解,还是有其他错误?
Code:
public class classIWantToTest implements classIWantToTestFacade{
@Autowired
private SomeService myService;
@Override
public Optional<OutputData> getInformations(final InputData inputData) {
final Optional<OutputData> data = myService.getListWithData(inputData);
if (data.isPresent()) {
final List<ItemData> allData = data.get().getItemDatas();
//do something with the data and allData
return data;
}
return Optional.absent();
}
}
这是我的测试类:
public class Test {
private InputData inputdata;
private ClassUnderTest classUnderTest;
final List<ItemData> allData = new ArrayList<ItemData>();
@Mock
private DeliveryItemData item1;
@Mock
private DeliveryItemData item2;
@Mock
private SomeService myService;
@Before
public void setUp() throws Exception {
classUnderTest = new ClassUnderTest();
myService = mock(myService.class);
classUnderTest.setService(myService);
item1 = mock(DeliveryItemData.class);
item2 = mock(DeliveryItemData.class);
}
@Test
public void test_sort() {
createData();
when(myService.getListWithData(inputdata).get().getItemDatas());
when(item1.hasSomething()).thenReturn(true);
when(item2.hasSomething()).thenReturn(false);
}
public void createData() {
item1.setSomeValue("val");
item2.setSomeOtherValue("test");
item2.setSomeValue("val");
item2.setSomeOtherValue("value");
allData.add(item1);
allData.add(item2);
}
10 回答
我有这个问题,我的问题是我用any()而不是anyInt()调用我的方法 . 所以我有:
我不得不把它改成:
我不知道为什么会产生NullPointerException . 也许这将有助于下一个可怜的灵魂 .
我有同样的问题,我的问题只是我没有使用@RunWith正确地注释该类 . 在您的示例中,请确保您具有:
一旦我这样做,NullPointerExceptions就消失了 .
您尚未存根的方法的默认返回值是
false
用于布尔方法,空集合或映射用于返回集合或映射的方法,否则为null
.这也适用于
when(...)
中的方法调用 . 在你的例子中when(myService.getListWithData(inputData).get())
将导致NullPointerException,因为myService.getListWithData(inputData)
是null
- 它之前没有被存根 .一个选项是为所有中间返回值创建模拟,并在使用前将它们存根 . 例如:
或者,您可以在创建模拟时指定不同的默认答案,以使方法返回新的模拟而不是null:
RETURNS_DEEP_STUBS
您应该阅读Mockito.RETURNS_DEEP_STUBS的Javadoc,它更详细地解释了这一点,并且还有一些关于其用法的警告 .
我希望这有帮助 . 请注意,您的示例代码似乎有更多问题,例如缺少断言或验证语句以及在模拟上调用setter(这没有任何影响) .
Corner case:
如果您正在使用 Scala 并尝试在 value class 上创建一个
any
匹配器,那么您将获得无用的NPE .所以
case class ValueClass(value: Int) extends AnyVal
,你要做的是ValueClass(anyInt)
而不是any[ValueClass]
另一个SO question更具体地说明了这一点,但是你知道这个问题与 Value 类有关 .
对我而言,我获得NPE的原因是我在模拟基元时使用了
Mockito.any()
. 我发现通过切换到使用mockito的正确变体来摆脱错误 .例如,要模拟一个以原始
long
作为参数而不是使用any()
的函数,您应该更具体,并将其替换为any(Long.class)
或Mockito.anyLong()
.希望能帮助别人 .
干杯
如果您使用 @Mock 注释
Context mockContext;
,则不需要{mockContext = Mockito.mock(Context.class);
}以上所有注释代码但是如果你只使用 @RunWith(MockitoJUnitRunner.class) 它会起作用 . 根据Mockito,您可以使用@Mock或Mockito.mock(Context.class)创建模拟对象; ,
因为使用了@RunWith(PowerMockRunner.class),我得到了NullpointerException,而不是我改为@RunWith(MockitoJUnitRunner.class)它工作正常
对于未来的读者来说,使用模拟时NPE的另一个原因是忘记初始化模拟,如下所示:
面对同样的问题,解决方案对我有用:
我使用@InjectMocks来模拟服务实现,而不是模拟服务接口:
代替 :
Ed Webb的answer在我的案例中有所帮助 . 相反,您也可以尝试添加
如果你
@RunWith(JUnit4.class)
.在我的情况下,我错过了先添加
所以这对看到这样的错误的人有帮助