Kyl*_*yle 47 java junit mocking mockito
我最近问了几个关于jUnit和Mockito的问题,我仍然在努力解决这个问题.这些教程都是非常简单的示例,所以我很难扩展我的测试用例以适应我的课程.
我正在尝试为我在webapp中的一个代理中的方法编写一些测试用例.该方法与代理内部的其他几种方法交互以验证某些对象.我现在只想测试这一种方法.
这是我试图做的事情:
像这样创建我的代理的Mockito对象:
MyProcessingAgent mockMyAgent = Mockito.mock(MyProcessingAgent.class);
使用Mockito.when设置存根(希望是正确的术语),如下所示:
Mockito.when(mockMyAgent.otherMethod(Mockito.any(arg1)).thenReturn(requiredReturnArg);
尝试执行我的方法,如下所示:
List myReturnValue = mockMyAgent.methodThatNeedsTestCase();
我期待的东西myReturnValue,但收到0反而所以我试图调试.当我调用该方法时,它永远不会执行.我在方法的第一行有一个调试点,永远不会被触及.
如果我想在类的一个方法中执行代码,但强制类中的其他方法(尝试与外部世界中的数据库交互的方法)返回伪造的值.这可能与Mockito一起吗?
看来我目前的方法不是一种正确的测试方式,但我不确定如何向前推进.我可以模拟我的类并让一个方法像正常一样执行,而其他方法被存根以返回我给定的值,这样我在测试这个方法时就不必处理数据访问了吗?
Bor*_*der 72
你混淆了Mock一个Spy.
在模拟中,所有方法都被存根并返回"智能返回类型".这意味着除非您指定行为,否则调用模拟类上的任何方法都不会执行任何操作.
在间谍中,类的原始功能仍然存在,但您可以在间谍中验证方法调用并覆盖方法行为.
你想要的是什么
MyProcessingAgent mockMyAgent = Mockito.spy(MyProcessingAgent.class);
Run Code Online (Sandbox Code Playgroud)
一个简单的例子:
static class TestClass {
public String getThing() {
return "Thing";
}
public String getOtherThing() {
return getThing();
}
}
public static void main(String[] args) {
final TestClass testClass = Mockito.spy(new TestClass());
Mockito.when(testClass.getThing()).thenReturn("Some Other thing");
System.out.println(testClass.getOtherThing());
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Some Other thing
Run Code Online (Sandbox Code Playgroud)
注意:您应该尝试模拟正在测试的类的依赖关系,而不是类本身.
因此,模拟测试类的想法是对测试实践的厌恶.你不应该这样做.因为你已经这样做了,你的测试是进入Mockito的模拟课程,而不是你正在测试的课程.
间谍也不会起作用,因为这只提供了一个围绕间谍类的包装器/代理.一旦执行在类中,它将不会通过代理,因此不会打到间谍.更新:虽然我相信这对于Spring代理来说是真实的,但对于Mockito间谍来说似乎并非如此.我设置了一个方法m1()调用的场景m2().我是间谍的对象和存根m2()到doNothing.当我m1()在我的测试中调用时,m2()没有到达类.Mockito调用存根.因此,使用间谍来完成所要求的事情是可能的.但是,我要重申,我认为这是不好的做法(恕我直言).
您应该模拟所测试的类所依赖的所有类.这将允许您控制被测方法调用的方法的行为,因为您可以控制这些方法调用的类.
如果您的类创建其他类的实例,请考虑使用工厂.