- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在调查我的项目使用哪个模拟框架,并将其范围缩小到 JMockit和 Mockito 。
我注意到 Mockito 在 Stackoverflow 上被评为“the best mock framework for Java ”。
在比较 JMockit 的“Mocking Tool Comparision Matrix”上的功能时,JMockit 似乎具有多个不同的功能。
是否有人对 Mockito 可以做什么而 JMockit 无法实现的事情有任何具体信息(不是意见),反之亦然?
最佳答案
2019 年 9 月更新:唯一的 mocking framework supported (by default) by Spring Boot是 Mockito 。如果你使用 Spring,答案就很明显了。
<小时/>我想说竞争是在JMockit和PowerMock之间,然后是Mockito。
我会留下“普通”jMock 和 EasyMock,因为它们仅使用代理和 CGLIB,并且不像较新的框架那样使用 Java 5 工具。
jMock 也已经有 4 年多没有发布稳定版本了。 jMock 2.6.0从RC1到RC2需要2年时间,然后又花了2年才真正发布。
关于代理和 CGLIB 与工具:
(EasyMock and jMock) are based on java.lang.reflect.Proxy, which requires an interface to be implemented. Additionally, they support the creation of mock objects for classes through CGLIB subclass generation. Because of that, said classes cannot be final and only overridable instance methods can be mocked. Most importantly, however, when using these tools the dependencies of code under test (that is, the objects of other classes on which a given class under test depends) must be controlled by the tests, so that mock instances can be passed to the clients of those dependencies. Therefore, dependencies can't simply be instantiated with the new operator in a client class for which we want to write unit tests.
Ultimately, the technical limitations of conventional mocking tools impose the following design restrictions on production code:
- Each class which may need to be mocked in a test must either implement a separate interface or not be final.
- The dependencies of each class to be tested must either be obtained through configurable instance creation methods (factories or a Service Locator), or be exposed for dependency injection. Otherwise, unit tests won't be able to pass mock implementations of dependencies to the unit under test.
- Since only instance methods can be mocked, classes to be unit tested cannot call any static methods on their dependencies, nor instantiate them using any of the constructors.
以上复制自http://jmockit.org/about.html 。此外,它在几个方面对自身 (JMockit)、PowerMock 和 Mockito 进行了比较:
There are now other mocking tools for Java which also overcome the limitations of the conventional ones, between them PowerMock, jEasyTest, and MockInject. The one that comes closest to the feature set of JMockit is PowerMock, so I will briefly evaluate it here (besides, the other two are more limited and don't seem to be actively developed anymore).
JMockit vs PowerMock
- First of all, PowerMock does not provide a complete API for mocking, but instead works as an extension to another tool, which currently can be EasyMock or Mockito. This is obviously an advantage for existing users of those tools.
- JMockit, on the other hand, provides entirely new APIs, although its main API (Expectations) is similar to both EasyMock and jMock. While this creates a longer learning curve, it also allows JMockit to provide a simpler, more consistent, and easier to use API.
- Compared to the JMockit Expectations API, the PowerMock API is more "low-level", forcing users to figure out and specify which classes need to be prepared for testing (with the @PrepareForTest({ClassA.class, ...}) annotation) and requiring specific API calls to deal with various kinds of language constructs that may be present in the production code: static methods (mockStatic(ClassA.class)), constructors (suppress(constructor(ClassXyz.class))), constructor invocations (expectNew(AClass.class)), partial mocks (createPartialMock(ClassX.class, "methodToMock")), etc.
- With JMockit Expectations, all kinds of methods and constructors are mocked in a purely declarative way, with partial mocking specified through regular expressions in the @Mocked annotation or by simply "un-mocking" the members with no recorded expectations; that is, the developer simply declares some shared "mock fields" for the test class, or some "local mock fields" and/or "mock parameters" for individual test methods (and in this last case the @Mocked annotation often won't be needed).
- Some capabilities available in JMockit, such as support for mocking equals and hashCode, overridden methods, and others, are currently not supported in PowerMock. Also, there is no equivalent to JMockit's ability to capture instances and mock implementations of specified base types as the test executes, without the test code itself having any knowledge of the actual implementation classes.
- PowerMock uses custom class loaders (usually one per test class) in order to generate modified versions of the mocked classes. Such heavy use of custom class loaders can lead to conflicts with third-party libraries, hence the need to sometimes use the @PowerMockIgnore("package.to.be.ignored") annotation on test classes.
- The mechanism used by JMockit (runtime instrumentation through a "Java agent") is simpler and safer, although it does require passing a "-javaagent" parameter to the JVM when developing on JDK 1.5; on JDK 1.6+ (which can always be used for development, even if deploying on an older version) there is no such requirement, since JMockit can transparently load the Java agent on demand by using the Attach API.
Another recent mocking tool is Mockito. Although it does not attempt to overcome the limitations of older tools (jMock, EasyMock), it does introduce a new style of behavior testing with mocks. JMockit also supports this alternative style, through the Verifications API.
JMockit vs Mockito
- Mockito relies on explicit calls to its API in order to separate code between the record (when(...)) and verify (verify(...)) phases. This means that any invocation to a mock object in test code will also require a call to the mocking API. Additionally, this will often lead to repetitive when(...) and verify(mock)... calls.
- With JMockit, no similar calls exist. Sure, we have the new NonStrictExpectations() and new Verifications() constructor calls, but they occur only once per test (typically), and are completely separate from the invocations to mocked methods and constructors.
- The Mockito API contains several inconsistencies in the syntax used for invocations to mocked methods. In the record phase, we have calls like when(mock.mockedMethod(args))... while in the verify phase this same call will be written as verify(mock).mockedMethod(args). Notice that in the first case the invocation to mockedMethod is made directly on the mock object, while in the second case it is made on the object returned by verify(mock).
- JMockit has no such inconsistencies because invocations to mocked methods are always made directly on the mocked instances themselves. (With one exception only: to match invocations on the same mocked instance, an onInstance(mock) call is used, resulting in code like onInstance(mock).mockedMethod(args); most tests won't need to use this, though.)
- Just like other mocking tools which rely on method chaining/wrapping, Mockito also runs into inconsistent syntax when stubbing void methods. For example, you write when(mockedList.get(1)).thenThrow(new RuntimeException()); for a non-void method, and doThrow(new RuntimeException()).when(mockedList).clear(); for a void one. With JMockit, it's always the same syntax: mockedList.clear(); result = new RuntimeException();.
- Yet another inconsistency occurs in the use of Mockito spies: "mocks" that allow the real methods to be executed on the spied instance. For example, if spy refers to an empty List, then instead of writing when(spy.get(0)).thenReturn("foo") you will need to write doReturn("foo").when(spy).get(0). With JMockit, the dynamic mocking feature provides similar functionality to spies, but without this issue since real methods only get executed during the replay phase.
- In EasyMock and jMock, the first mocking APIs for Java, the focus was entirely on the recording of expected invocations of mocked methods, for mock objects that (by default) do not allow unexpected invocations. Those APIs also provide the recording of allowed invocations for mock objects that do allow unexpected invocations, but this was treated as a second-class feature. Additionally, with these tools there is no way to explicitly verify invocations to mocks after the code under test is exercised. All such verifications are performed implicitly and automatically.
- In Mockito (and also in Unitils Mock), the opposite viewpoint is taken. All invocations to mock objects that may happen during the test, whether recorded or not, are allowed, never expected. Verification is performed explicitly after the code under test is exercised, never automatically.
- Both approaches are too extreme, and consequently less than optimal. JMockit Expectations & Verifications is the only API that allows the developer to seamlessly choose the best combination of strict (expected by default) and non-strict (allowed by default) mock invocations for each test.
- To be more clear, the Mockito API has the following shortcoming. If you need to verify that an invocation to a non-void mocked method happened during the test, but the test requires a return value from that method that is different from the default for the return type, then the Mockito test will have duplicate code: a when(mock.someMethod()).thenReturn(xyz) call in the record phase, and a verify(mock).someMethod() in the verify phase. With JMockit, a strict expectation can always be recorded, which won't have to be explicitly verified. Alternatively, an invocation count constraint (times = 1) can be specified for any recorded non-strict expectation (with Mockito such constraints can only be specified in a verify(mock, constraint) call).
- Mockito has poor syntax for verifications in order, and for full verifications (that is, checking that all invocations to mock objects are explicitly verified). In the first case, an extra object needs to be created, and calls to verify made on it: InOrder inOrder = inOrder(mock1, mock2, ...). In the second case, calls like verifyNoMoreInteractions(mock) or verifyZeroInteractions(mock1, mock2) need to be made.
- With JMockit, you simply write new VerificationsInOrder() or new FullVerifications() instead of new Verifications() (or new FullVerificationsInOrder() to combine both requirements). No need to specify which mock objects are involved. No extra mocking API calls. And as a bonus, by calling unverifiedInvocations() inside an ordered verification block, you can perform order-related verifications that are simply impossible in Mockito.
Finally, the JMockit Testing Toolkit has a wider scope and more ambitious goals than other mocking toolkits, in order to provide a complete and sophisticated developer testing solution. A good API for mocking, even without artificial limitations, is not enough for productive creation of tests. An IDE-agnostic, easy to use, and well integrated Code Coverage tool is also essential, and that's what JMockit Coverage aims to provide. Another piece of the developer testing toolset which will become more useful as the test suite grows in size is the ability to incrementally rerun tests after a localized change to production code; this is also included in the Coverage tool.
(当然,来源可能有偏见,但好吧......)
我建议选择JMockit。它是最容易使用、灵活的,并且适用于几乎所有情况,甚至是当您无法控制要测试的类(或者由于兼容性原因等而无法破坏它)时的困难情况和场景。
我使用 JMockit 的经历非常积极。
关于java - Mockito 与 JMockit 之间的比较 - 为什么 Mockito 比 JMockit 更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4105592/
据我所知,根本不为元素呈现 HTML,或添加 display:none,似乎具有完全相同的行为:两者都使元素消失并且不与 HTML 交互。 我正在尝试禁用和隐藏一个复选框。所以HTML的总量很小;我无
我刚刚读了Android Architecture Tutorial: Developing an App with a Background Service (using IPC) .基本上是 让服
我有两个查询具有相同的结果,现在我想知道哪个查询更优化? 在选择中: select t1.*, sum(t2.value) as total_votes from table1 t1 left joi
有人告诉我,对于 I/O 绑定(bind)的应用程序,非阻塞 I/O 会更好。对于 CPU 密集型应用程序,阻塞 I/O 会好得多。我找不到这种说法的原因。试过谷歌,但很少有文章只是触及这个话题而没有
我有一个算法可以在数字列表中寻找好的对。一个好的配对被认为是索引 i 小于 j 且 arr[i] 1: # Finding the mid of the array
我有一个算法可以在数字列表中寻找好的对。一个好的配对被认为是索引 i 小于 j 且 arr[i] 1: # Finding the mid of the array
我从 API 收到一个 json,我需要解析并修改一个属性值。问题是,我收到的 json 数据的嵌套结构不一致,我无法控制它。 这将禁止我指定在特定深度(如 parsedJson.children[0
我有 451 个城市的坐标。现在我想计算每个城市之间的距离,然后根据该距离对一些结果进行排序。现在我有两个选择: 我可以运行一个循环来计算每个可能的城市组合的距离并将它们存储到一个表中,这将产生大约
对于返回相同结果的不同查询,我有两个查询计划我想知道是否有人可以告诉我哪个“更好”,以及为什么。 SELECT * FROM bids order by (select ranking from us
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 7 年前。 Improve this qu
我有一个二维数组。我需要尽可能快地对其执行一些操作(函数每秒将被调用十几次,所以让它变得高效会很好)。 现在,假设我想获取元素 A[i][j],简单地使用 A[i][j] 在速度上有什么不同吗和 *(
在声明或使用字符串的代码中,我通常会看到开发人员这样声明它: string randomString = @"C:\Random\RandomFolder\ThisFile.xml"; 代替: str
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Why don't CSS resets use '*' to cover all elements? 我正
如果我有一个包含许多重复项的 python 列表,并且我想遍历每个项目,而不是重复项,最好使用一个集合(如 set(mylist),或者找到另一种方法来创建没有重复的列表?我想只是循环遍历列表并检查重
在阅读常量接口(interface)反模式时,我发现没有实例的最终常量类比常量接口(interface)更好。 请解释一下怎么做? public interface ConstIfc { publ
我正在查看我继承的一些旧代码,我真的不喜欢某些地方的风格。我真的不喜欢它的外观的一件事是: bool func() { bool ret = true; ret &= test1();
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
我经常发现自己试图使用 boost/QT 信号解耦对象。实现这一点的简单方法是针对我要通信的每个具体类型,创建一个新的信号和插槽签名并连接所有相关对象。这导致了访问者模式,理想情况下我想发出一个访问者
我正在 https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html 上阅读有关 lambda 的内容 在方法
public List getInts() { List xs = new ArrayList(); xs.add(1); // return Collections.unmo
我是一名优秀的程序员,十分优秀!