Khung mô phỏng tốt nhất cho Java là gì? [đóng cửa]


347

Khuôn khổ tốt nhất để tạo các đối tượng giả trong Java là gì? Tại sao? Những ưu và nhược điểm của từng khung là gì?

Câu trả lời:


315

Tôi đã thành công khi sử dụng Mockito .

Khi tôi cố gắng tìm hiểu về JMock và EasyMock, tôi thấy đường cong học tập hơi dốc (mặc dù có lẽ đó chỉ là tôi).

Tôi thích Mockito vì cú pháp đơn giản và rõ ràng của nó mà tôi có thể nắm bắt khá nhanh. Cú pháp tối thiểu được thiết kế để hỗ trợ rất tốt cho các trường hợp phổ biến, mặc dù vài lần tôi cần làm gì đó phức tạp hơn, tôi thấy những gì tôi muốn được hỗ trợ và dễ nắm bắt.

Đây là một ví dụ (được rút ngắn) từ trang chủ Mockito:

import static org.mockito.Mockito.*;

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

Nó không đơn giản hơn thế nhiều.

Nhược điểm lớn duy nhất tôi có thể nghĩ đến là nó sẽ không chế nhạo các phương thức tĩnh.


15
Xinh đẹp. Đối với các phương thức tĩnh, chỉ cần kết hợp Mockito với JMockit và thực tế không có lớp nào quá "di sản" để bạn có thể kiểm tra.
Epaga

6
Tôi thích cách bạn cố gắng làm điều gì đó mà bạn không nên (ví dụ: tạo mock nội tuyến), bạn sẽ nhận được một lời giải thích rất rõ ràng về những gì bạn đã làm sai trong thông báo ngoại lệ.
ripper234

3
Đối với tôi, hoàn toàn. Tôi vẫn sẽ giới thiệu nó vô điều kiện. Tất nhiên, nếu bạn tìm thấy một khung khác đáp ứng tốt hơn nhu cầu của bạn, hãy đề cập đến nó trong một câu trả lời khác và xem nó nhận được phiếu bầu nào và loại bình luận nào nhận được.
Brian Laframboise

2
@MexicanHacker tại sao bạn không thể sử dụng nó cho Android? Tôi đang sử dụng nó ngay bây giờ, với Robolectric.
Ilkka

2
Tôi đang sử dụng Mockito và yêu thích nó !! Tài liệu tuyệt vời cũng vậy (rất hiếm khi tìm thấy tài liệu có chất lượng này, công việc tốt từ các tác giả), điều này rất quan trọng đối với chúng tôi để sử dụng công cụ mà không cần phải đào sâu vào mã của khung !!!
Renato

84

Tôi là người tạo ra PowerMock nên rõ ràng tôi phải khuyên bạn điều đó! :-)

PowerMock mở rộng cả EasyMock và Mockito với khả năng mô phỏng các phương thức tĩnh , phương thức cuối cùng và thậm chí là riêng tư. Hỗ trợ EasyMock đã hoàn tất, nhưng plugin Mockito cần thêm một số công việc. Chúng tôi đang lên kế hoạch để thêm hỗ trợ JMock là tốt.

PowerMock không có ý định thay thế các khung công tác khác, thay vào đó, nó có thể được sử dụng trong các tình huống khó khăn khi các khung công tác khác không cho phép chế nhạo. PowerMock cũng chứa các tính năng hữu ích khác như chặn các trình khởi tạohàm tạo tĩnh .


Powermock rất cần thiết để kiểm tra đơn vị các ứng dụng Android bằng Java gốc trên PC chủ (tránh sử dụng trình giả lập chậm)
Jeff Axelrod

@Jan chỉ có vấn đề là PowerMock không tương thích khi sử dụng Robolectric mặc dù :-( Tôi muốn làm @RunWith (PowerMockRunner. Class) VÀ @RunWith (RobolectricTestRunner. Class)
Blundell

Sau khi sử dụng PowerMock trong vài tháng qua, tôi chân thành khuyên bạn nên dùng nó!
cwash

PowerMock thực sự là tuyệt vời. Tôi thực sự yêu thích các singletons tĩnh để truy cập mọi thứ, và điều này có thể kiểm tra.
Ian Macalinao

Hãy cẩn thận: một số thứ như chế độ nhạo báng cuối cùng chỉ có thể có trong Powermock cho EasyMock chứ không phải cho Mockito. Đó là một chút vấn đề khi bạn không sử dụng nó thường xuyên. Tôi đã tự hỏi tại sao một cái gì đó không hoạt động sau đó tôi nhận ra nó chỉ được liệt kê dưới phần Easymock của tài liệu.
trafalmadorian

46

Các khu vực dự án JMockit chứa rất nhiều thông tin so sánh cho các bộ công cụ mocking hiện hành.

Cụ thể, hãy kiểm tra ma trận so sánh tính năng , bao gồm EasyMock, jMock, Mockito, Unitils Mock, PowerMock, và dĩ nhiên là JMockit. Tôi cố gắng giữ cho nó chính xác và cập nhật, càng nhiều càng tốt.


1
Tôi ấn tượng bởi JMockit, nó có một đường cong học tập dốc hơn, nhưng nó có tài liệu rất tốt trong nhiều năm, và nó có thể chế giễu bất cứ điều gì. Tôi bắt đầu với Mockito, một thứ dễ học, nhưng tôi thường xuyên gặp những vấn đề mà tôi không thể giải quyết được. Mặt khác, tôi thậm chí không thể tưởng tượng được điều gì là không thể với JMockit.
Hontvári Levente

21

Tôi đã thành công với JMockit .

Nó khá mới, và do đó, nó hơi thô và chưa được ghi chép đầy đủ. Nó sử dụng ASM để xác định lại động theo mã byte lớp, do đó nó có thể mô phỏng tất cả các phương thức bao gồm tĩnh, riêng, hàm tạo và khởi tạo tĩnh. Ví dụ:

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...
}

Nó cũng có giao diện Expectations cho phép ghi lại các kịch bản / phát lại:

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

Nhược điểm là nó yêu cầu Java 5/6.


vâng, thực sự có thể đề nghị điều này
Epaga

7
Chỉ cần một bản cập nhật: dự án JMockit đã chuyển sang code.google.com/p/jmockit . Nó đã phát triển rất nhiều kể từ bài đăng này (và vẫn đang phát triển), và bây giờ có tài liệu rộng rãi.
Rogério

JMockit đã di chuyển một lần nữa. Hiện đã có tại Github. jmockit.github.io
Ravi Thapliyal

15

Bạn cũng có thể xem thử nghiệm bằng Groovy. Trong Groovy, bạn có thể dễ dàng mô phỏng các giao diện Java bằng cách sử dụng toán tử 'as':

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

Ngoài chức năng cơ bản này, Groovy cung cấp nhiều hơn nữa trên mặt trận chế giễu, bao gồm cả các lớp mạnh mẽ MockForStubForđẳng cấp.

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


13

Tôi bắt đầu sử dụng giả với EasyMock . Đủ dễ hiểu, nhưng bước phát lại hơi khó chịu. Mockito loại bỏ điều này, cũng có một cú pháp rõ ràng hơn vì có vẻ như khả năng đọc là một trong những mục tiêu chính của nó. Tôi không thể nhấn mạnh đủ tầm quan trọng của việc này, vì hầu hết các nhà phát triển sẽ dành thời gian đọc và duy trì mã hiện có, không tạo ra nó.

Một điều tuyệt vời nữa là các giao diện và các lớp triển khai được xử lý theo cùng một cách, không giống như trong EasyMock, nơi bạn vẫn cần nhớ (và kiểm tra) để sử dụng tiện ích mở rộng lớp EasyMock.

Gần đây tôi đã xem qua JMockit và trong khi danh sách các tính năng giặt là khá toàn diện, tôi nghĩ giá của điều này là mức độ dễ đọc của mã kết quả và phải viết thêm.

Đối với tôi, Mockito đạt đến điểm ngọt ngào, dễ viết và đọc và xử lý hầu hết các tình huống mà hầu hết các mã sẽ yêu cầu. Sử dụng Mockito với PowerMock sẽ là lựa chọn của tôi.

Một điều cần xem xét là công cụ bạn sẽ chọn nếu bạn tự phát triển hoặc trong một nhóm nhỏ chặt chẽ, có thể không phải là công cụ tốt nhất để có được cho một công ty lớn với các nhà phát triển có trình độ kỹ năng khác nhau. Dễ đọc, dễ sử dụng và đơn giản sẽ cần xem xét nhiều hơn trong trường hợp sau. Không có ý nghĩa trong việc có được khuôn khổ chế giễu cuối cùng nếu nhiều người cuối cùng không sử dụng nó hoặc không duy trì các bài kiểm tra.


1
+1 Câu trả lời này cần nhiều sự ủng hộ hơn. Người ta nên chia sẻ những gì họ thực sự thích hoặc không về khuôn khổ. Chỉ "Tôi đã sử dụng cái này .. và tôi thích nó!" là một trong những lý do tại sao các câu hỏi hay như vậy lại bị đóng trên SO.
Ravi Thapliyal

11

Chúng tôi đang sử dụng EasyMock và EasyMock Class Extension trong công việc và khá hài lòng với nó. Về cơ bản nó cung cấp cho bạn mọi thứ bạn cần. Hãy xem tài liệu này, có một ví dụ rất hay cho bạn thấy tất cả các tính năng của EasyMock.


1
Trong câu hỏi của tôi, tôi đã tìm kiếm nhiều hơn những gì bạn thích và không thích về một khung giả. Tôi có thể tìm tài liệu và đọc tất cả về nó - tôi muốn biết những người đã sử dụng nó nghĩ gì về nó.
Josh Brown

EasyMock chỉ hoạt động trên Java 5 trở lên, argh!
matt b

8

Tôi đã sử dụng JMock sớm. Tôi đã thử Mockito tại dự án cuối cùng của tôi và thích nó. Ngắn gọn hơn, sạch sẽ hơn. PowerMock đáp ứng tất cả các nhu cầu vắng mặt trong Mockito, chẳng hạn như chế nhạo mã tĩnh, chế nhạo một tạo cá thể, chế nhạo các lớp và phương thức cuối cùng. Vì vậy, tôi có tất cả những gì tôi cần để thực hiện công việc của mình.


6

Tôi thích JMock vì bạn có thể thiết lập kỳ vọng. Điều này hoàn toàn khác với việc kiểm tra nếu một phương thức được gọi là tìm thấy trong một số thư viện giả. Sử dụng JMock bạn có thể viết những kỳ vọng rất tinh vi. Xem jmock cheat-sheat .



4

Giải pháp tốt nhất để chế nhạo là để máy thực hiện mọi công việc với thử nghiệm dựa trên đặc tả tự động. Đối với Java, hãy xem ScalaCheck và khung Reductio có trong thư viện Java Chức năng . Với các khung kiểm tra dựa trên đặc tả tự động, bạn tự động cung cấp một đặc tả của phương thức được kiểm tra (một thuộc tính về nó phải đúng) và khung tự động tạo ra các kiểm tra cũng như các đối tượng giả.

Ví dụ, thuộc tính sau kiểm tra phương thức Math.sqrt để xem căn bậc hai của bất kỳ số dương nào n bình phương có bằng n không.

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

Khi bạn gọi propSqrt.check(), ScalaCheck tạo ra hàng trăm số nguyên và kiểm tra từng thuộc tính của bạn, cũng tự động đảm bảo rằng các trường hợp cạnh được bảo vệ tốt.

Mặc dù ScalaCheck được viết bằng Scala và yêu cầu Trình biên dịch Scala, thật dễ dàng để kiểm tra mã Java với nó. Khung Reductio trong Java chức năng là một triển khai Java thuần túy của các khái niệm tương tự.


3

Mockito cũng cung cấp tùy chọn các phương pháp stubbing, phù hợp với đối số (như anyInt () và anyString ()), xác minh số của lời gọi (lần (3), atLeastOnce (), không bao giờ ()), và nhiều hơn nữa .

Tôi cũng thấy rằng Mockito đơn giản và sạch sẽ .

Một điều tôi không thích ở Mockito là bạn không thể bỏ qua các phương thức tĩnh .


Câu trả lời này không chính xác. Bạn không bị giới hạn giao diện với jMock. Bạn có thể giả định các lớp cụ thể với ClassImposteriser.
Teflon Ted

Bạn cũng có thể làm chính xác những điều tương tự với EasyMock.
Cem Catikkas

Tôi đã loại bỏ những điểm không chính xác khỏi câu trả lời của tôi.
Josh Brown

2

Đối với một cái gì đó hơi khác một chút, bạn có thể sử dụng JRubyMocha được kết hợp trong JtestR để viết các bài kiểm tra cho mã Java của bạn bằng Ruby biểu cảm và cô đọng. Có một số ví dụ chế giễu hữu ích với JtestR ở đây . Một lợi thế của phương pháp này là việc chế nhạo các lớp bê tông rất đơn giản.


1

Tôi bắt đầu sử dụng giả thông qua JMock, nhưng cuối cùng đã chuyển sang sử dụng EasyMock. EasyMock chỉ như vậy, --easier-- và cung cấp một cú pháp cảm thấy tự nhiên hơn. Tôi đã không chuyển từ đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.