我使用mockito作为mocking框架。这里有一个场景,我的when(abc.method()).thenReturn(value)不返回值,而是返回null。
public class DQExecWorkflowServiceImplTest {
@InjectMocks
DQExecWorkflowServiceImpl dqExecWorkflowServiceImpl = new DQExecWorkflowServiceImpl();
@Mock
private DQUtility dqUtility;
@Mock
private DqExec dqExec;
@Mock
private DqCntlDefn dqCntlDefn;
@Mock
private DqCntlWfDefn dqCntlWfDefn;
@Mock
private DqCntlWfDefnTyp dqCntlWfDefnTyp;
@Mock
private IDQControlWfDefTypeService controlWfDefTypeService;
@Before
public void setUp() throws Exception {
dqExec = new DqExec();
dqCntlWfDefn = new DqCntlWfDefn();
dqUtility = new DQUtility();
dqCntlWfDefnTyp = new DqCntlWfDefnTyp();
dqCntlWfDefnTyp.setDqCntlWfDefnTypCd("MIN_INCLUSIVE_VAL");
dqExecWorkflowServiceImpl
.setControlWfDefTypeService(controlWfDefTypeService);
}
@Test
public void testExecuteWorkflow() {
when(controlWfDefTypeService.getDqCntlWfDefnTypCd(dqCntlWfDefn))
.thenReturn(dqCntlWfDefnTyp);
dqExecWorkflowServiceImpl.executeWorkflow(dqExec, dqCntlWfDefn);
}
}
Java类
@Override
public DqCntlWfExec executeWorkflow(final DqExec dqExec,
final DqCntlWfDefn dqCntlWfDefn) {
final DqCntlWfExec dqCntlWfExec = new DqCntlWfExec();
dqCntlWfExec.setDqCntlWfExecEffDt(dqUtil.getDefaultEffectiveDt());
dqCntlWfExec.setDqCntlWfExecExpDt(dqUtil.getDefaultExpiryDt());
dqCntlWfExec.setDqCntlWfDefn(dqCntlWfDefn);
dqCntlWfExec.setDqExec(dqExec);
final DqCntlWfDefnTyp dqCntlWfDefnTyp = controlWfDefTypeService
.getDqCntlWfDefnTypCd(dqCntlWfDefn);
String workflowType = null;
if(null!=dqCntlWfDefnTyp){
workflowType = dqCntlWfDefnTyp.getDqCntlWfDefnTypCd();
}
当我运行测试文件时,When不起作用,并且我在构建路径中使用mockito1.8.5jar。服务调用正在被模拟,但返回null值。
final DqCntlWfDefnTyp dqCntlWfDefnTyp = controlWfDefTypeService
.getDqCntlWfDefnTypCd(dqCntlWfDefn);
此对象dqCntlWfDefnTyp为空
我以前做过这个,什么时候没有问题,似乎是用我以前做的文件。我对测试文件采用了同样的程序,但我无法解决问题。有人能帮我吗
感谢所有提前到达的人
Mockito mock在我们松散地模拟对象时起作用。
以下是我为使其发挥作用所做的更改:
when(controlWfDefTypeService.getDqCntlWfDefnTypCd(any(DqCntlWfDefn.class))
.thenReturn(dqCntlWfDefnTyp);
我没有传递Mock类的对象,而是传递了带有Matcher any()
的类,它就工作了。
TL;DR如果测试中的某些参数是null
,请确保使用isNull()
而不是any(SomeClass.class)
模拟参数调用。
解释
这可能不是帮助OP的答案,但可能对其他人有用。在我的情况下,设置都很好,但是,有些mock返回了所需的thenReturn(...)
值,有些则没有。
重要的是要理解,您试图模拟的方法调用(即when(someMock.methodToMock)
中的方法)必须匹配实际调用,而不是仅匹配签名。
在我的例子中,我模拟了一种带有签名的方法:
public void SomeValue method(String string, SomeParam param)
然而,在测试中的电话是这样的:
method("some string during test", null);
现在,如果你用模拟通话
when(MockedClass.method(anyString(), any(SomeParam.class))
即使签名正确,Mockito也不会匹配它。问题是Mockito正在寻找一个参数为String
和SomeParam
的method()
调用,而实际调用是String
和null
。你要做的是:
when(MockedClass.method(anyString(), isNull())
提示
由于在不同的框架中有许多isNull()
实现,所以一定要使用这一个org.mockito.ArgumentMatchers.isNull
。
我也遇到了同样的问题。对我来说,解决方案是放Mockito。when(…)。然后Return(…);进入@Before SetUp方法。
我想我已经找到了你的问题,但并不是所有的功劳都归我。
由于您试图在测试类中模拟"dqCntlWfDefnTyp",并且对象本身正在您试图测试的类中实例化,因此不可避免地会遇到一些问题。主要的问题是无法对对象进行模拟,因为在测试期间正在中重新创建该对象。
有一些选择,但在我看来,最好的选择是使用PowerMockito。您将能够用您模拟的对象替换正在测试的类中的对象。
关于这个问题,@raspacorp的PowerMockito的一个很好的例子是:
public class MyClass {
void method1{
MyObject obj1=new MyObject();
obj1.method1();
}
}
还有测试班。。。
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MyClassTest {
@Test
public void testMethod1() {
MyObject myObjectMock = mock(MyObject.class);
when(myObjectMock.method1()).thenReturn(<whatever you want to return>);
PowerMockito.whenNew(MyObject.class).withNoArguments().thenReturn(myObjectMock);
MyClass objectTested = new MyClass();
objectTested.method1();
... // your assertions or verification here
}
}
正如Younes EO所说:它通常与传递给模拟函数的null
参数有关。
值得补充的一点是,如果您在测试中使用Kotlin(并且您的项目中有mockito-kotlin
),那么对于Nullable
参数,您应该通常使用anyOrNull()
而不是any()
。
与主题相关,以防这对某人有所帮助。当断言anyString()
时,我的mockito.when
不起作用,原因是测试类中的String
是从属性文件注入的值。以下行设置单元测试中的注入值:
ReflectionTestUtils.setField(bean, "theVariable", "theValue");
我在测试controler时遇到了同样的问题。使用@MockBean代替@Mock