Saya telah menulis beberapa tes unit untuk metode statis. Metode statis hanya membutuhkan satu argumen. Jenis argumen adalah kelas akhir. Dalam hal kode:
public class Utility {
public static Optional<String> getName(Customer customer) {
// method's body.
}
}
public final class Customer {
// class definition
}
Jadi untuk Utility
kelas saya telah membuat kelas tes UtilityTests
di mana saya telah menulis tes untuk metode ini getName
,. Kerangka pengujian unit adalah TestNG dan perpustakaan mocking yang digunakan adalah Mockito
. Jadi tes khas memiliki struktur berikut:
public class UtilityTests {
@Test
public void getNameTest() {
// Arrange
Customer customerMock = Mockito.mock(Customer.class);
Mockito.when(...).thenReturn(...);
// Act
Optional<String> name = Utility.getName(customerMock);
// Assert
Assert.assertTrue(...);
}
}
Apa masalahnya ?
Sedangkan tes berjalan dengan sukses secara lokal, di dalam IntelliJ, mereka gagal pada Jenkins (ketika saya mendorong kode saya di cabang jarak jauh, sebuah build dipicu dan unit test dijalankan pada akhirnya). Pesan kesalahannya sth seperti berikut:
org.mockito.exceptions.base.MockitoException: Tidak dapat mengejek / memata-matai kelas com.packagename.Pelanggan Mockito tidak dapat mengejek / memata-matai karena: - kelas akhir
Apa yang saya coba?
Saya mencari sedikit, untuk menemukan solusi tetapi saya tidak berhasil. Saya perhatikan di sini bahwa saya tidak diizinkan mengubah fakta bahwa Customer
ini adalah kelas akhir . Selain itu, saya ingin jika mungkin untuk tidak mengubah desainnya sama sekali (misalnya membuat antarmuka, yang akan menampung metode yang ingin saya tiru dan menyatakan bahwa kelas Pelanggan mengimplementasikan antarmuka itu, seperti yang ditunjukkan oleh Jose dengan tepat dalam bukunya). komentar). Hal yang saya coba adalah pilihan kedua yang disebutkan di mockito-final . Terlepas dari kenyataan bahwa ini memperbaiki masalah, rem beberapa tes unit lain :(, yang tidak dapat diperbaiki dengan cara yang tidak jelas.
Pertanyaan
Jadi, inilah dua pertanyaan yang saya miliki:
- Bagaimana itu mungkin terjadi? Bukankah seharusnya tes gagal baik lokal maupun Jenkins?
- Bagaimana ini dapat diperbaiki berdasarkan kendala yang saya sebutkan di atas?
Terima kasih sebelumnya atas bantuannya.
sumber
enable final
konfigurasi berfungsi di ruang kerja Anda, tetapi ketika dijalankanJenkins
tidak dapat menemukan file ini. Periksa di manaJenkins
mencari file dan apakah itu benar-benar ada atau tidak.Customer
ada logika di dalamnya, atau hanya kelas data yang bodoh? Jika hanya sekelompok bidang dengan getter dan setter, maka Anda bisa langsung instantiate.Jawaban:
Pendekatan alternatif adalah dengan menggunakan pola 'metode untuk kelas'.
Inilah blog yang bagus tentang topik ini: https://simpleprogrammer.com/back-to-basics-mock-eliminating-patterns/
sumber
Ini jelas semacam env-spesifik. Satu-satunya pertanyaan adalah - bagaimana menentukan penyebab perbedaan.
Saya sarankan Anda untuk memeriksa
org.mockito.internal.util.MockUtil#typeMockabilityOf
metode dan membandingkan, apamockMaker
yang sebenarnya digunakan di kedua lingkungan dan mengapa.Jika
mockMaker
sama - bandingkan kelas yang dimuatIDE-Client
vsJenkins-Client
- apakah mereka memiliki perbedaan pada waktu pelaksanaan tes.Kode berikut ditulis dengan asumsi OpenJDK 12 dan Mockito 2.28.2, tetapi saya yakin Anda dapat menyesuaikannya dengan versi yang benar-benar digunakan.
Dengan aturan terpisah untuk inline mock:
sumber
Pastikan Anda menjalankan tes dengan argumen yang sama. Periksa apakah konfigurasi menjalankan intellij Anda cocok dengan jenkins. https://www.jetbrains.com/help/idea/creating-and-editing-run-debug-configurations.html . Anda dapat mencoba menjalankan tes pada mesin lokal dengan argumen yang sama seperti pada jenkins (dari terminal), jika gagal maka itu berarti masalahnya ada pada argumen
sumber
org.mockito.plugins.MockMaker
itu ada juga di mesin jenkins. Saya menggunakan JVM yang sama di mesin bot. Saya akan memeriksa 3 yang Anda tunjukkan. Terima kasih