方法不工作时的Mockito

ugmeyewa  于 2022-11-08  发布在  其他
关注(0)|答案(7)|浏览(154)

我使用mockito作为模拟框架。我这里有一个场景,我的when(abc.method()).thenReturn(value)不返回值,而是返回空值。

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();
}

当我运行测试文件时,当我在buildpath中使用mockito1.8.5 jar时,测试文件不起作用。服务调用被模拟,但返回空值。

final DqCntlWfDefnTyp dqCntlWfDefnTyp = controlWfDefTypeService
    .getDqCntlWfDefnTypCd(dqCntlWfDefn);

此对象dqCntlWfDefnTyp为空
我以前做过这个,没有问题的时候,它似乎是与我以前做过的文件工作。我已经遵循了相同的程序测试文件,但我不能弄清楚的问题。有人可以请协助我吗
提前感谢各位乡亲

atmip9wb

atmip9wb1#

当我们松散地模仿对象时,Mockito mock就可以工作。
下面是我为使它工作所做的更改:

when(controlWfDefTypeService.getDqCntlWfDefnTypCd(any(DqCntlWfDefn.class))
    .thenReturn(dqCntlWfDefnTyp);

我没有传递Mock类的对象,而是用Matcher any()传递了该类,它工作了。

xfyts7mz

xfyts7mz2#

TL;DR如果测试中的某些参数是null,请确保使用 * isNull() * 而不是 * any(SomeClass.class) * 模拟参数调用。
说明

这可能不是帮助OP的答案,但可能对其他人有用。在我的例子中,设置都很好,但是,一些模拟返回了所需的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正在查找带有参数StringSomeParammethod()调用,而实际调用是带有String和**null**的。您需要做的是:

when(MockedClass.method(anyString(), isNull())

提示

因为在不同的框架中有许多isNull()实现,所以一定要使用这个org.mockito.ArgumentMatchers.isNull

8ehkhllq

8ehkhllq3#

我想我已经找到了你的问题,但并不是所有的功劳都归我。
由于您尝试在测试类中模拟'dqCntlWfDefnTyp',并且对象本身在您尝试测试的类中被示例化,因此您不可避免地遇到一些问题。主要问题是无法模拟对象,因为在测试期间正在中重新创建它。
有几个选项,但我认为最好的选择是使用PowerMockito。您将能够用您模拟的对象替换正在测试的类中的对象。
在此question上使用来自@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 
}
}
e7arh2l6

e7arh2l64#

我也遇到了同样的问题。对我来说,解决办法是把Mockito.when(...).thenReturn(...);导入@Before-SetUp方法。

yc0p9oo0

yc0p9oo05#

就像Younes EO说的那样:它通常与传递给模拟函数的null参数有关。
值得补充的一点是,如果您使用Kotlin进行测试(并且您的项目中有mockito-kotlin),对于Nullable参数,您通常应该使用anyOrNull()而不是any()

mbjcgjjk

mbjcgjjk6#

与主题相关,只是为了帮助某些人。当AssertanyString()时,我的mockito.when不工作,原因是被测试类中的String是来自属性文件的注入值。下面一行设置了单元测试中的注入值:

ReflectionTestUtils.setField(bean, "theVariable", "theValue");
q35jwt9p

q35jwt9p7#

我在测试控制器时遇到了同样的问题。使用@MockBean而不是@Mock

相关问题