Java 的最佳模拟框架是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:15:04  来源:igfitidea点击:

What's the best mock framework for Java?

javaunit-testingmocking

提问by Josh Brown

What's the best framework for creating mock objects in Java? Why? What are the pros and cons of each framework?

在 Java 中创建模拟对象的最佳框架是什么?为什么?每个框架的优缺点是什么?

采纳答案by Brian Laframboise

I've had good success using Mockito.

我使用Mockito取得了很好的成功。

When I tried learning about JMock and EasyMock, I found the learning curve to be a bit steep (though maybe that's just me).

当我尝试学习 JMock 和 EasyMock 时,我发现学习曲线有点陡峭(尽管可能只有我这样)。

I like Mockito because of its simple and clean syntax that I was able to grasp pretty quickly. The minimal syntax is designed to support the common cases very well, although the few times I needed to do something more complicated I found what I wanted was supported and easy to grasp.

我喜欢 Mockito,因为它的语法简单干净,我能够很快掌握。最小语法旨在很好地支持常见情况,尽管有几次我需要做一些更复杂的事情,但我发现我想要的东西得到支持并且易于掌握。

Here's an (abridged) example from the Mockito homepage:

这是 Mockito 主页上的(节略的)示例:

import static org.mockito.Mockito.*;

List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();

It doesn't get much simpler than that.

没有比这更简单的了。

The only major downside I can think of is that it won't mock static methods.

我能想到的唯一主要缺点是它不会模拟静态方法。

回答by dlinsin

We are heavily using EasyMockand EasyMock Class Extension at work and are pretty happy with it. It basically gives you everything you need. Take a look at the documentation, there's a very nice example which shows you all the features of EasyMock.

我们在工作中大量使用EasyMock和 EasyMock 类扩展,并且对它非常满意。它基本上为您提供了所需的一切。看一下文档,有一个非常好的示例,它向您展示了 EasyMock 的所有功能。

回答by Mike Furtak

I started using mocks through JMock, but eventually transitioned to use EasyMock. EasyMock was just that, --easier-- and provided a syntax that felt more natural. I haven't switched since.

我开始通过 JMock 使用模拟,但最终过渡到使用 EasyMock。EasyMock 就是这样,--更简单-- 并提供了一种感觉更自然的语法。从那以后我就没有换过。

回答by Josh Brown

Mockito also provides the option of stubbing methods, matching arguments (like anyInt() and anyString()), verifying the number of invocations (times(3), atLeastOnce(), never()), and more.

Mockito 还提供了存根方法、匹配参数(如 anyInt() 和 anyString())、验证调用次数(times(3)、atLeastOnce()、never())等选项

I've also found that Mockito is simple and clean.

我还发现 Mockito 既简单又干净

One thing I don't like about Mockito is that you can't stub static methods.

我不喜欢 Mockito 的一件事是你不能存根静态方法

回答by Bartosz Bierkowski

Yes, Mockito is a great framework. I use it together with hamcrestand Google guiceto setup my tests.

是的,Mockito 是一个很棒的框架。我将它与hamcrestGoogle guice一起使用来设置我的测试。

回答by p3t0r

You could also have a look at testing using Groovy. In Groovy you can easily mock Java interfaces using the 'as' operator:

您还可以查看使用 Groovy 进行测试。在 Groovy 中,您可以使用“as”运算符轻松模拟 Java 接口:

def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest 

Apart from this basic functionality Groovy offers a lot more on the mocking front, including the powerful MockForand StubForclasses.

除了这些基本功能的Groovy提供了更多的嘲笑前,包括强大的MockForStubFor类。

http://docs.codehaus.org/display/GROOVY/Groovy+Mocks

http://docs.codehaus.org/display/GROOVY/Groovy+Mocks

回答by Kris Pruden

I've been having success with JMockit.

我在JMockit上取得了成功。

It's pretty new, and so it's a bit raw and under-documented. It uses ASMto dynamically redefine the class bytecode, so it can mock out all methods including static, private, constructors, and static initializers. For example:

它很新,所以有点原始和记录不足。它使用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...
}

It has an Expectations interface allowing record/playback scenarios as well:

它有一个 Expectations 界面,允许录制/播放场景:

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";
      }
    }
  }
}

The downside is that it requires Java 5/6.

缺点是它需要 Java 5/6。

回答by Andrea Francia

I like JMock because you are able to set up expectations. This is totally different from checking if a method was called found in some mock libraries. Using JMock you can write very sophisticated expectations. See the jmock cheat-sheat.

我喜欢 JMock,因为你可以设置期望值。这与检查是否在某些模拟库中找到调用方法完全不同。使用 JMock,您可以编写非常复杂的期望。请参阅 jmock作弊工具

回答by Jan Kronquist

I am the creator of PowerMock so obviously I must recommend that! :-)

我是 PowerMock 的创建者,所以显然我必须推荐它!:-)

PowerMockextends both EasyMock and Mockito with the ability to mock static methods, final and even private methods. The EasyMock support is complete, but the Mockito plugin needs some more work. We are planning to add JMock support as well.

PowerMock扩展了 EasyMock 和 Mockito,具有模拟静态方法、最终方法甚至私有方法的能力。EasyMock 支持已经完成,但 Mockito 插件还需要做一些工作。我们也计划添加 JMock 支持。

PowerMock is not intended to replace other frameworks, rather it can be used in the tricky situations when other frameworks does't allow mocking. PowerMock also contains other useful features such as suppressing static initializersand constructors.

PowerMock 并不是要取代其他框架,而是可以在其他框架不允许模拟的棘手情况下使用它。PowerMock 还包含其他有用的功能,例如抑制静态初始化器和构造器。

回答by Apocalisp

The best solution to mocking is to have the machine do all the work with automated specification-based testing. For Java, see ScalaCheckand the Reductioframework included in the Functional Javalibrary. With automated specification-based testing frameworks, you supply a specification of the method under test (a property about it that should be true) and the framework generates tests as well as mock objects, automatically.

模拟的最佳解决方案是让机器通过基于规范的自动化测试来完成所有工作。对于 Java,请参阅函数式 Java库中包含的ScalaCheckReductio框架。使用基于规范的自动化测试框架,您提供被测方法的规范(关于它的属性应该是真的),框架会自动生成测试以及模拟对象。

For example, the following property tests the Math.sqrt method to see if the square root of any positive number n squared is equal to n.

例如,以下属性测试 Math.sqrt 方法以查看任何正数 n squared 的平方根是否等于 n。

val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }

When you call propSqrt.check(), ScalaCheck generates hundreds of integers and checks your property for each, also automatically making sure that the edge cases are covered well.

当您调用 时propSqrt.check(),ScalaCheck 会生成数百个整数并为每个整数检查您的属性,同时还会自动确保边缘情况被很好地覆盖。

Even though ScalaCheck is written in Scala, and requires the Scala Compiler, it's easy to test Java code with it. The Reductio framework in Functional Java is a pure Java implementation of the same concepts.

尽管 ScalaCheck 是用 Scala 编写的,并且需要 Scala 编译器,但使用它测试 Java 代码很容易。Functional Java 中的 Reductio 框架是相同概念的纯 Java 实现。