用Java创建模拟对象的最佳框架是什么?为什么?每个框架的优点和缺点是什么?
当前回答
我开始使用EasyMock模拟。很容易理解,但重放步骤有点烦人。Mockito删除了这一点,也有一个更清晰的语法,因为可读性似乎是它的主要目标之一。我再怎么强调这一点也不为过,因为大多数开发人员会花时间阅读和维护现有代码,而不是创建它。
另一个好处是接口和实现类以相同的方式处理,不像在EasyMock中,您仍然需要记住(并检查)使用EasyMock类扩展。
我最近快速浏览了一下JMockit,虽然它的特性清单非常全面,但我认为这样做的代价是代码的易读性,并且必须编写更多的代码。
对我来说,Mockito达到了最佳的位置,易于编写和阅读,并处理大多数代码所需要的大多数情况。使用Mockito和PowerMock将是我的选择。
需要考虑的一件事是,如果您是独自开发,或者在一个小型紧密的团队中开发,那么对于拥有不同技能水平的开发人员的大公司来说,您所选择的工具可能不是最佳选择。对于后一种情况,需要更多地考虑可读性、易用性和简洁性。如果许多人最终不使用或不维护测试,那么获得最终的mock框架是没有意义的。
其他回答
我很早就使用了JMock。我在我的最后一个项目中尝试了Mockito,并喜欢它。更简洁,更干净。PowerMock涵盖了Mockito中没有的所有需求,比如模拟静态代码、模拟实例创建、模拟最终类和方法。这样我就有了完成工作所需的一切。
是的,Mockito是一个很棒的框架。我使用它与hamcrest和谷歌guice一起设置我的测试。
我已经成功地使用了JMockit。
它是相当新的,所以它有点原始,文档不足。它使用ASM动态地重新定义类字节码,因此它可以模拟所有方法,包括静态、私有、构造函数和静态初始化器。例如:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
它有一个期望界面,允许记录/回放场景以及:
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
缺点是它需要Java 5/6。
Mockito还提供了存根方法、匹配参数(如anyInt()和anyString())、验证调用次数(times(3)、atLeastOnce()、never())等选项。
我还发现Mockito简单干净。
我不喜欢Mockito的一点是你不能存根静态方法。
我开始通过JMock使用mock,但最终过渡到使用EasyMock。EasyMock就是这样——更简单——并提供了一种感觉更自然的语法。从那以后我就没换过。
推荐文章
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂
- Java:检查enum是否包含给定的字符串?
- 它的意思是:序列化类没有声明一个静态的最终serialVersionUID字段?