Apa kerangka kerja mock terbaik untuk Java? [Tutup]

347

Apa kerangka kerja terbaik untuk membuat objek tiruan di Jawa? Mengapa? Apa pro dan kontra dari setiap kerangka kerja?

Josh Brown
sumber

Jawaban:

315

Saya sudah sukses menggunakan Mockito .

Ketika saya mencoba belajar tentang JMock dan EasyMock, saya menemukan kurva belajar agak curam (meskipun mungkin itu hanya saya).

Saya suka Mockito karena sintaksisnya yang sederhana dan bersih yang dapat saya pahami dengan cepat. Sintaks minimal dirancang untuk mendukung kasus-kasus umum dengan sangat baik, walaupun beberapa kali saya perlu melakukan sesuatu yang lebih rumit, saya menemukan apa yang saya inginkan didukung dan mudah dipahami.

Inilah contoh (ringkas) dari beranda Mockito:

import static org.mockito.Mockito.*;

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

Itu tidak menjadi jauh lebih sederhana dari itu.

Satu-satunya downside utama yang dapat saya pikirkan adalah bahwa itu tidak akan mengejek metode statis.

Brian Laframboise
sumber
15
Cantik. Untuk metode statis, cukup gabungkan Mockito dengan JMockit dan praktis tidak ada kelas terlalu "warisan" bagi Anda untuk dapat menguji.
Epaga
6
Saya suka bagaimana ketika Anda mencoba melakukan sesuatu yang seharusnya tidak Anda lakukan (mis. Membuat mock inline), Anda mendapatkan penjelasan yang sangat jelas tentang apa yang Anda lakukan salah dalam pesan pengecualian.
ripper234
3
Bagi saya, tentu saja. Saya masih akan merekomendasikan itu tanpa syarat. Tentu saja, jika Anda menemukan kerangka kerja lain yang lebih baik memenuhi kebutuhan Anda, sebutkan itu di jawaban lain dan lihat suara apa yang didapat dan jenis komentar apa yang diterimanya.
Brian Laframboise
2
@MexicanHacker mengapa Anda tidak bisa menggunakannya untuk Android? Saya menggunakannya sekarang, dengan Robolectric.
Ilkka
2
Saya menggunakan Mockito dan menyukainya !! Dokumentasi hebat juga (sangat jarang menemukan dokumentasi dengan kualitas ini, pekerjaan bagus dari penulis), yang sangat penting bagi kami untuk menggunakan hal-hal tanpa harus menggali ke dalam kode kerangka kerja !!!
Renato
84

Saya pencipta PowerMock jadi jelas saya harus merekomendasikan itu! :-)

PowerMock memperluas EasyMock dan Mockito dengan kemampuan untuk mengejek metode statis , final dan bahkan metode pribadi. Dukungan EasyMock sudah selesai, tetapi plugin Mockito membutuhkan lebih banyak pekerjaan. Kami berencana untuk menambahkan dukungan JMock juga.

PowerMock tidak dimaksudkan untuk menggantikan kerangka kerja lain, melainkan dapat digunakan dalam situasi sulit ketika kerangka kerja lain tidak memungkinkan mengejek. PowerMock juga mengandung fitur berguna lainnya seperti menekan inisialisasi statis dan konstruktor.

Jan Kronquist
sumber
Powermock sangat penting untuk pengujian unit aplikasi Android menggunakan Java asli pada PC host (menghindari penggunaan emulator lambat)
Jeff Axelrod
@Jan satu-satunya masalah adalah PowerMock tidak kompatibel ketika menggunakan Robolectric :-( Saya ingin melakukan @RunWith (PowerMockRunner.class) AND @RunWith (RobolectricTestRunner.class)
Blundell
Setelah menggunakan PowerMock selama beberapa bulan terakhir saya sungguh-sungguh merekomendasikannya!
cwash
PowerMock sungguh luar biasa. Saya sangat suka lajang statis untuk mengakses semuanya, dan ini memungkinkan untuk menguji.
Ian Macalinao
Peringatan: beberapa hal seperti metode final yang mengejek hanya mungkin di Powermock untuk EasyMock dan bukan untuk Mockito. Ini sedikit pahit ketika Anda tidak sering menggunakannya. Saya bertanya-tanya mengapa sesuatu tidak berfungsi maka saya menyadari itu hanya terdaftar di bawah bagian Easymock dari dokumen.
trafalmadorian
46

Situs proyek JMockit berisi banyak informasi komparatif untuk toolkit mengejek saat ini.

Secara khusus, periksa matriks perbandingan fitur , yang mencakup EasyMock, jMock, Mockito, Unitils Mock, PowerMock, dan tentu saja JMockit. Saya berusaha untuk tetap akurat dan mutakhir, sebanyak mungkin.

Rogério
sumber
1
Saya terkesan oleh JMockit, ia memiliki kurva belajar yang lebih curam, tetapi memiliki dokumentasi yang sangat baik selama bertahun-tahun, dan dapat mengejek apa pun. Saya mulai dengan Mockito, yang mudah dipelajari, tetapi saya secara teratur menemui masalah yang tidak bisa saya selesaikan. Di sisi lain saya bahkan tidak bisa membayangkan apa yang tidak mungkin dengan JMockit.
Hontvári Levente
21

Saya sudah sukses dengan JMockit .

Ini cukup baru, jadi sedikit mentah dan kurang didokumentasikan. Ia menggunakan ASM untuk secara dinamis mendefinisikan kembali bytecode kelas, sehingga ia dapat mencemooh semua metode termasuk statis, privat, konstruktor, dan penginisialisasi statis. Sebagai contoh:

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

Ini memiliki antarmuka Ekspektasi yang memungkinkan skenario rekaman / pemutaran juga:

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

Kelemahannya adalah itu membutuhkan Java 5/6.

Kris Pruden
sumber
ya, benar-benar dapat merekomendasikan ini
Epaga
7
Hanya pembaruan: proyek JMockit pindah ke code.google.com/p/jmockit . Ini telah berkembang BANYAK sejak posting ini (dan masih terus berkembang), dan sekarang memiliki dokumentasi yang luas.
Rogério
JMockit telah pindah lagi. Sekarang tersedia di Github. jmockit.github.io
Ravi Thapliyal
15

Anda juga bisa melihat pengujian menggunakan Groovy. Di Groovy Anda dapat dengan mudah mengejek antarmuka Java menggunakan operator 'as':

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

Terlepas dari fungsi dasar ini, Groovy menawarkan lebih banyak hal untuk mengejek, termasuk kelas yang tangguh MockFordan StubForberkelas.

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

p3t0r
sumber
13

Saya mulai menggunakan ejekan dengan EasyMock . Cukup mudah dimengerti, tetapi langkah replay agak menjengkelkan. Mockito menghapus ini, juga memiliki sintaks yang lebih bersih karena sepertinya keterbacaan adalah salah satu tujuan utamanya. Saya tidak bisa cukup menekankan betapa pentingnya hal ini, karena sebagian besar pengembang akan menghabiskan waktu mereka membaca dan memelihara kode yang ada, tidak membuatnya.

Hal lain yang menyenangkan adalah antarmuka dan kelas implementasi ditangani dengan cara yang sama, tidak seperti di EasyMock di mana Anda masih perlu mengingat (dan memeriksa) untuk menggunakan Ekstensi Kelas EasyMock.

Saya telah mengambil pandangan cepat di JMockit baru-baru ini, dan sementara daftar fitur binatu cukup komprehensif, saya pikir harga ini dapat dibaca dari kode yang dihasilkan, dan harus menulis lebih banyak.

Bagi saya, Mockito menyentuh sweet spot, mudah menulis dan membaca, dan berurusan dengan sebagian besar situasi yang paling dibutuhkan kode. Menggunakan Mockito dengan PowerMock akan menjadi pilihan saya.

Satu hal yang perlu dipertimbangkan adalah bahwa alat yang akan Anda pilih jika Anda mengembangkan sendiri, atau dalam tim kecil, mungkin bukan yang terbaik untuk perusahaan besar dengan pengembang dari berbagai tingkat keterampilan. Keterbacaan, kemudahan penggunaan dan kesederhanaan akan membutuhkan lebih banyak pertimbangan dalam kasus terakhir. Tidak masuk akal untuk mendapatkan kerangka kerja ejekan utama jika banyak orang yang akhirnya tidak menggunakannya atau tidak melakukan tes.

trafalmadorian
sumber
1
+1 Jawaban ini membutuhkan lebih banyak suara positif. Seseorang harus membagikan apa yang sebenarnya mereka sukai atau tidak tentang kerangka itu. Hanya "Saya menggunakan ini .. dan saya menyukainya!" adalah salah satu alasan mengapa pertanyaan bagus seperti itu ditutup pada SO.
Ravi Thapliyal
11

Kami banyak menggunakan EasyMock dan Ekstensi Kelas EasyMock di tempat kerja dan cukup senang dengannya. Ini pada dasarnya memberi Anda semua yang Anda butuhkan. Lihatlah dokumentasi, ada contoh yang sangat bagus yang menunjukkan kepada Anda semua fitur EasyMock.

dlinsin
sumber
1
Dalam pertanyaan saya, saya lebih mencari apa yang Anda sukai dan tidak suka tentang kerangka tiruan. Saya dapat menemukan dokumentasinya dan membaca semua tentangnya - Saya ingin tahu apa pendapat orang-orang yang telah menggunakannya.
Josh Brown
EasyMock hanya berfungsi di Java 5 dan di atas, argh!
matt b
8

Saya menggunakan JMock lebih awal. Saya sudah mencoba Mockito di proyek terakhir saya dan menyukainya. Lebih ringkas, lebih bersih. PowerMock mencakup semua kebutuhan yang tidak ada di Mockito, seperti mengejek kode statis, mengejek pembuatan instance, mengejek kelas dan metode akhir. Jadi saya memiliki semua yang saya butuhkan untuk melakukan pekerjaan saya.

Dmitry
sumber
6

Saya suka JMock karena Anda dapat mengatur harapan. Ini sama sekali berbeda dari memeriksa apakah suatu metode dipanggil ditemukan di beberapa perpustakaan tiruan. Menggunakan JMock Anda dapat menulis harapan yang sangat canggih. Lihat jmock cheat-sheat .

Andrea Francia
sumber
5

Ya, Mockito adalah kerangka kerja yang hebat. Saya menggunakannya bersama dengan hamcrest dan Google guice untuk mengatur tes saya.

Bartosz Bierkowski
sumber
4

Solusi terbaik untuk mengejek adalah membuat mesin melakukan semua pekerjaan dengan pengujian berbasis spesifikasi otomatis. Untuk Java, lihat ScalaCheck dan kerangka kerja Reductio yang termasuk dalam perpustakaan Java Fungsional . Dengan kerangka kerja pengujian berbasis spesifikasi otomatis, Anda memberikan spesifikasi metode yang diuji (properti tentang hal itu yang seharusnya benar) dan kerangka kerja menghasilkan tes serta benda tiruan, secara otomatis.

Sebagai contoh, properti berikut menguji metode Math.sqrt untuk melihat apakah akar kuadrat dari setiap bilangan positif n kuadrat sama dengan n.

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

Ketika Anda menelepon propSqrt.check(), ScalaCheck menghasilkan ratusan bilangan bulat dan memeriksa properti Anda untuk masing-masing, juga secara otomatis memastikan bahwa kasing tepi tertutup dengan baik.

Meskipun ScalaCheck ditulis dalam Scala, dan membutuhkan Scala Compiler, mudah untuk menguji kode Java dengannya. Kerangka kerja Reductio di Java Fungsional adalah implementasi Java murni dari konsep yang sama.

Apocalisp
sumber
3

Mockito juga menyediakan opsi metode stubbing, argumen yang cocok (seperti anyInt () dan anyString ()), memverifikasi jumlah doa (kali (3), atLeastOnce (), never ()), dan banyak lagi .

Saya juga menemukan bahwa Mockito sederhana dan bersih .

Satu hal yang saya tidak suka dari Mockito adalah Anda tidak bisa mematikan metode statis .

Josh Brown
sumber
Jawaban ini tidak akurat. Anda tidak terbatas pada antarmuka dengan jMock. Anda dapat mengejek kelas konkret dengan ClassImposteriser.
Teflon Ted
Anda dapat melakukan hal yang persis sama dengan EasyMock juga.
Cem Catikkas
Saya telah menghapus ketidakakuratan dari jawaban saya.
Josh Brown
2

Untuk sesuatu yang sedikit berbeda, Anda bisa menggunakan JRuby dan Mocha yang digabungkan dalam JtestR untuk menulis tes untuk kode Java Anda dalam Ruby ekspresif dan ringkas. Ada beberapa contoh mengejek yang berguna dengan JtestR di sini . Salah satu keuntungan dari pendekatan ini adalah bahwa kelas beton mengejek sangat mudah.

James Mead
sumber
1

Saya mulai menggunakan mock melalui JMock, tetapi akhirnya beralih menggunakan EasyMock. EasyMock hanya itu, - lebih mudah - dan memberikan sintaks yang terasa lebih alami. Saya belum beralih sejak.

Mike Furtak
sumber