Java 方法不起作用时的 Mockito

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20517618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:29:41  来源:igfitidea点击:

Mockito when method not working

javamockito

提问by Gopi

I am using mockito as mocking framework. I have a scenerio here, my when(abc.method()).thenReturn(value) does not return value, instead it returns null.

我使用 mockito 作为模拟框架。我这里有一个场景,我的 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 class

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 ever i run the test file the when is not working and i am using mockito1.8.5 jar in the buildpath. The service call is being mocked but returns the null value.

当我运行测试文件时,当它不起作用时,我在构建路径中使用了 mockito1.8.5 jar。正在模拟服务调用但返回空值。

final DqCntlWfDefnTyp dqCntlWfDefnTyp = controlWfDefTypeService
    .getDqCntlWfDefnTypCd(dqCntlWfDefn);

This object dqCntlWfDefnTyp is null

此对象 dqCntlWfDefnTyp 为空

I have done this before and there was no problem with the when, It seems to be working with files i have done before. I had followed the same procedure for the test file but i couldnt figure out the issue. Can anyone please assist me

我以前做过这个,时间没有问题,它似乎正在处理我以前做过的文件。我对测试文件遵循了相同的程序,但我无法弄清楚问题所在。任何人都可以帮助我

Thanks to all the folks in advance

提前感谢所有的人

采纳答案by Gopi

Mockito mock works when we mock the objects loosely.

当我们松散地模拟对象时,Mockito 模拟工作。

Here is the change i have made to make it work:

这是我为使其工作所做的更改:

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

Instead of passing the object of the Mock class, I passed the class with the Matcher any()and it works.

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

回答by Chad Van De Hey

I think I have found your issue, but not all the credit goes to me.

我想我已经发现了您的问题,但并非所有功劳都归功于我。

Since you are trying to mock 'dqCntlWfDefnTyp' in your test class and the object itself is being instantiated in the class that you are trying to test, you inevitably run into some issues. The primary problem is that the object cannot be mocked because it is being recreated in during the test.

由于您尝试在测试类中模拟“dqCntlWfDefnTyp”,并且对象本身正在您尝试测试的类中实例化,因此您不可避免地会遇到一些问题。主要问题是对象不能被模拟,因为它在测试期间被重新创建。

There are a few options, but the best choice in my humble opinion is using PowerMockito. You will be able to replace the object within the class that is being tested with the one you mock.

有几种选择,但在我看来,最好的选择是使用PowerMockito。您将能够用您模拟的对象替换正在测试的类中的对象。

An excellent example of this usage of PowerMockito from @raspacorp on this question:

@raspacorp 在这个问题上使用 PowerMockito 的一个很好的例子:

public class MyClass {
void method1{
    MyObject obj1=new MyObject();
    obj1.method1();
}
}

And the test class...

还有考试班...

@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 
}
}

回答by Lazar Zoltan

I had the same problem. The solution for me was to put the Mockito.when(...).thenReturn(...); into the @Before-SetUp method.

我有同样的问题。我的解决方案是把 Mockito.when(...).thenReturn(...); 进入@Before-SetUp 方法。

回答by CoffeeConverter2000 Pro

TL;DRIf some arguments in your test are null, be sure to mock the parameter call with isNull()instead of any(SomeClass.class).

TL;DR如果测试中的某些参数是null,请务必使用isNull()而不是模拟参数调用any(SomeClass.class)



Explanation

解释

This might not be the answer that helps OP, but might be useful for someone else. In my case the setup was all good, however, some mocks returned the desired thenReturn(...)value and some didn't.

这可能不是帮助 OP 的答案,但可能对其他人有用。在我的情况下,设置都很好,但是,有些模拟返回了所需的thenReturn(...)值,有些则没有。

It's important to understand, that the method call you're trying to mock (i.e. the method in when(someMock.methodToMock)) has to match the actual call and notthe signature only.

重要的是要了解,您尝试模拟的方法调用(即 中的方法when(someMock.methodToMock))必须与实际调用相匹配而不仅仅是签名

In my case, I mocked a method with a signature:

就我而言,我嘲笑了一个带有签名的方法:

public void SomeValue method(String string, SomeParam param)

The call however, in the test was something like:

然而,在测试中的调用是这样的:

method("some string during test", null);

Now if you mock the call with:

现在,如果你模拟调用:

when(MockedClass.method(anyString(), any(SomeParam.class))

Mockito will not match it even though the signature is correct. The problem is that Mockito is looking for a call of method()with the arguments Stringand SomeParam, whereas the actual call was with a Stringand null. What you have to do is:

即使签名正确,Mockito 也不会匹配它。问题是 Mockito 正在寻找method()带有参数StringandSomeParam的调用,而实际调用是带有Stringand 的null。你需要做的是:

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


Hint

暗示

Since there are many isNull()implementations in different frameworks, be sure to use this one org.mockito.ArgumentMatchers.isNull.

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