我想模拟一个类上的所有方法以返回一个结果,而不是分别模拟每个方法,比如:
mock(Foo.class, allMethodsWithAnyArgs).thenReturn('abc');
我是Java测试的新手,所以请原谅这个愚蠢的问题。这个巨大的项目有Mockito,PowerMockito、PowerMock、EasyMock,可能还有其他东西,所以我可以使用任何推荐的东西。
一个扩展的例子是这样的,我需要测试Foo:
public class Foo {
doSomething(){
Bar bar = new bar();
// some code
bar.x(a);
// some code
bar.x(a, b, c);
// some more code
bar.y(...);
// even more code
bar.z(...);
}
}
我需要拦截所有的酒吧电话,但不在乎回报,或者我想要相同的回报,比如说他们所有人的1或"ok",等等。
更新:我同意这不是最好的测试代码,这里是我在这种情况下尝试测试的最新示例,所以我需要存根MyUtil和bar方法,它们是静态的,所以你建议我如何重构它们?对我来说,把MyUtil作为一个必要的参数是没有意义的,如果可能的话,我更愿意让Foo保持静态。一个有效的测试文件将不胜感激,因为我已经在这种事情上挣扎了几天了。
public class Foo {
public static Object doSomething(Long id){
Bar bar = new Bar();
Object obj;
if(somecondition) {
Long vnumber = MyUtil.getVNumber(id);
obj = bar.getCurrentObj(id, vnumber);
} else {
obj = bar.getPreviousObj(id);
}
bar.z(obj);
....
}
}
此外,这个类的一个要点是使它成为一个黑盒,我不希望被调用方担心创建实例并将其传入,甚至不希望知道事情是如何工作的,我只想传递一个ID并获得它的结果。例如,一些调用函数甚至无法访问Bar,所以我不能将其作为必需的参数。
有这么多方法要模拟可能是一个类有太多责任的迹象。
然而,mock并不是唯一的测试替身。可能更适合您的用例的是假的。
这实际上取决于Foo
在一个接口后面:
interface Bar {
String x(String s);
String y(String s);
}
然后你就有了你的产品实现:
class RealBar implements Bar {
@Override
String x(String s) {
// whatever your production logic is
}
}
然后你在test
源集中的测试中使用的一个赝品:
class FakeBar implements Bar {
@Override
String x(String s) {
return "abc";
}
}
因为这个赝品是开箱即用的,所以你可以重用它,而不必手动为它存根行为
如果您在Foo
中使用构造函数注入,那么您的测试将包括传入伪造的Bar
,而不是生成的Bar
@Before
public void setUp() {
foo = new Foo(new FakeBar());
}
因此,伪造是避免手动清除负担的公认方式。
然而,如果除了存根化类的每个方法以返回相同的值之外别无选择,那么这不是一个常见的用例,大多数mocking库也不太可能支持它。尤其是当Mockito试图在类设计上固执己见,以防止您编写次优代码时。
可以手动编写代码,使用反射来查找声明的方法,然后存根行为。当你这样做的时候,可能已经执行了"提取接口"并写了一个假的。