在Mock对象上调用方法是调用实际方法而不是模拟实现(Calling a method on Mock object is calling real method instead of mocked implementation)

我有我的代码如下

public process() { extract(); ... } private Obj extract() { Constructor const = new Constructor(); Obj object = const.getOBJMethod("12345","c:/file/a.zip",null); return object; }

我正在使用mockito测试方法过程。 在我的测试课中,我编写了代码

Constructor mocckConst = mock(Constructor.class); Obj mockObject = mock(Obj.class); when(mocckConst .getOBJMethod("12345","c:/file/a.zip",null).thenReturn(mockObject);

但是当调用extract方法执行testcase时,它将转向getOBJMethod()的实际实现。

构造函数类有另一个内部类。 这会导致任何问题吗? 任何人都可以告诉我这里出了什么问题和解决方案。

我想即兴创作我的流程方法。

public process(String base) { if("abc".equals(base)) { --- } else if("def".equals(base) { extract(); --- } }

这样,只有在基础为def时才调用extract()。 我不想将构造函数对象传递给process()方法然后有任何解决方案吗?

I have my code like below

public process() { extract(); ... } private Obj extract() { Constructor const = new Constructor(); Obj object = const.getOBJMethod("12345","c:/file/a.zip",null); return object; }

I am testing the method process using mockito. and in my test class I have written code as

Constructor mocckConst = mock(Constructor.class); Obj mockObject = mock(Obj.class); when(mocckConst .getOBJMethod("12345","c:/file/a.zip",null).thenReturn(mockObject);

But while execution of testcase when extract method is called it is going to the real implementation of getOBJMethod().

Constructor class has another inner class. Does that cause any problem? Can anybody tell me what is going wrong here and the solution.

I would like to improvise my process method.

public process(String base) { if("abc".equals(base)) { --- } else if("def".equals(base) { extract(); --- } }

This way extract() is called only when basis is def. and I don't want to pass constructor object to process() method then are there any solutions?

最满意答案

在要测试的类中,创建一个新的Constructor对象(通过Constructor const = new Constructor() ),因此,您始终使用REAL实现。 如果要将模拟对象替换为测试对象,则必须注入Constructor对象。 注入也可以通过构造函数进行测试。

private final Constructor const; // remove final, if required public <ConstructorOfYourClassHere>(Constructor const) { assert const != null : "const != null"; // use assertions, if you like this.const = const; // other constructor code... } // your other code here... public process(String base) { if("abc".equals(base)) { // --- } else if("def".equals(base) { extract(); // --- } } private Obj extract() { Obj object = const.getOBJMethod("12345","c:/file/a.zip",null); return object; }

然后,您可以在创建测试对象时调用模拟并调用process() 。 然后将使用您的模拟实现。

BTW

如果您是代码的所有者,则可能需要将extract方法的可见性更改为protected以便您也可以测试该方法。 看到这里 。 此外,您可能希望阅读有关依赖注入的内容。 使用DI进行测试通常要容易得多。 您不必使用DI框架,只需通过方法参数注入依赖项,或者在创建对象时通过构造函数注入依赖项。

In the class that you want to test you create a new Constructor object (via Constructor const = new Constructor()), hence, you always use the REAL implementation. You have to inject the Constructor object if you want to have it replaced by a mock object for testing. Injection is also possible via constructor for testing.

private final Constructor const; // remove final, if required public <ConstructorOfYourClassHere>(Constructor const) { assert const != null : "const != null"; // use assertions, if you like this.const = const; // other constructor code... } // your other code here... public process(String base) { if("abc".equals(base)) { // --- } else if("def".equals(base) { extract(); // --- } } private Obj extract() { Obj object = const.getOBJMethod("12345","c:/file/a.zip",null); return object; }

Then you can inject the mock when you create the object under test and call process(). Then your mock implementation will be used.

BTW:

If you're the owner of the code, you might want to change the visibility of the extract method to protected so that you can test the method, too. See here. Also, you might want to read something about dependency injection in general. Testing with DI is often much easier. You don't have to use a DI-framework, just inject your dependencies via method parameters or via constructor at object creation time.

更多推荐