2015-02-24 30 views
5

Tôi cần một số lời khuyên sử dụng jmockit với kotlin.Sử dụng kotlin với jmockit

(CUT) Đây là của tôi (Java) lớp dưới kiểm tra:

public final class NutritionalConsultant { 
    public static boolean isLunchTime() { 
     int hour = LocalDateTime.now().getHour(); 
     return hour >= 12 && hour <= 14; 
    } 
} 

(j.1) Đây là một lớp thử nghiệm Java làm việc

@RunWith(JMockit.class) 
public class NutritionalConsultantTest { 
    @Test 
    public void shouldReturnTrueFor12h(@Mocked final LocalDateTime dateTime) { 
     new Expectations() {{ 
      LocalDateTime.now(); result = dateTime; 
      dateTime.getHour(); result = 12; 
     }}; 
     boolean isLunchTime = NutritionalConsultant.isLunchTime(); 
     assertThat(isLunchTime, is(true)); 
    } 
} 

(kt.1) Tuy nhiên, lớp Kotlin tương ứng ném một ngoại lệ

RunWith(javaClass<JMockit>()) 
public class NutritionalConsultantKt1Test { 

    Test 
    public fun shouldReturnTrueFor12h(Mocked dateTime : LocalDateTime) { 
     object : Expectations() {{ 
      LocalDateTime.now(); result = dateTime; 
      dateTime.getHour(); result = 12; 
     }} 
     val isLunchTime = NutritionalConsultant.isLunchTime() 
     assertThat(isLunchTime, eq(true)); 
    } 
} 

ngoại lệ:

java.lang.Exception: Method shouldReturnTrueFor12h should have no parameters 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:41) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 

Cùng một ngoại lệ được ném khi chạy bằng gradle.

(kt.2) Sử dụng cú pháp @Mocked với Kotlin Tôi nhận được một ngoại lệ khác nhau:

RunWith(javaClass<JMockit>()) 
public class NutritionalConsultantKt2Test { 
    Mocked 
    var dateTime : LocalDateTime by Delegates.notNull() 

    Test 
    public fun shouldReturnTrueFor12h() { 
     object : Expectations() {{ 
      LocalDateTime.now(); result = dateTime; 
      dateTime.getHour(); result = 12; 
     }} 
     val isLunchTime = NutritionalConsultant.isLunchTime() 
     assertThat(isLunchTime, eq(true)); 
    } 
} 

Ngoại lệ:

java.lang.IllegalArgumentException: Final mock field "dateTime$delegate" must be of a class type 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 

chỉnh sửa 20.150.224 có lẽ đây có liên quan đến "Đối với một trường mô hình, một thể hiện của kiểu khai báo sẽ được tạo tự động bởi JMockit và được gán cho trường, miễn là nó không phải là cuối cùng. " (từ http://jmockit.org/tutorial/BehaviorBasedTesting.html)

(kt.3) Tuy nhiên, thay đổi val thành var và sử dụng !! nhà điều hành dẫn đến thử nghiệm hoạt động ... nhưng đây không phải là mã kotlin thành ngữ:

RunWith(javaClass<JMockit>()) 
public class NutritionalConsultantKt3Test { 
    Mocked 
    var dateTime : LocalDateTime? = null 

    Test 
    public fun shouldReturnTrueFor12h() { 
     object : Expectations() {{ 
      LocalDateTime.now(); result = dateTime; 
      dateTime!!.getHour(); result = 12; 
     }} 
     val isLunchTime = NutritionalConsultant.isLunchTime() 
     assertThat(isLunchTime, eq(true)); 
    } 
} 

Bạn có thành công hơn khi sử dụng kotlin với jmockit không?

Trả lời

0

Tôi không nghĩ rằng bạn sẽ có thể sử dụng JMockit từ Kotlin (hoặc hầu hết các ngôn ngữ thay thế JVM khác, ngoại trừ Groovy), không đáng tin cậy.

Lý do là 1) JMockit không được phát triển với các ngôn ngữ như vậy trong tâm trí và không được thử nghiệm với chúng; và 2) các ngôn ngữ này, khi được biên dịch sang bytecode, tạo ra các cấu trúc bổ sung hoặc khác nhau có thể gây nhầm lẫn một công cụ như JMockit; họ cũng thường chèn các cuộc gọi đến các API nội bộ của riêng họ mà cũng có thể bị cản trở.

Trong thực tế, các ngôn ngữ thay thế có xu hướng phát triển thử nghiệm/mocking/v.v. các công cụ, không chỉ hoạt động tốt cho ngôn ngữ đó và thời gian chạy của nó, mà còn cho phép bạn tận dụng tối đa các lợi ích của ngôn ngữ đó.

Cá nhân, mặc dù tôi có thể nhận ra nhiều lợi ích như ngôn ngữ mang lại (và tôi đặc biệt thích Kotlin), tôi thà gắn bó với Java (tiếp tục phát triển - xem Java 8). Thực tế là, cho đến nay không có ngôn ngữ JVM thay thế thậm chí còn gần với việc sử dụng rộng rãi của Java và (IMO) chúng sẽ không bao giờ xảy ra.

+0

> Tôi thà gắn bó với Java (tiếp tục phát triển - xem Java 8) Chỉ muốn lưu ý rằng điều này không đúng trên Android. –

+0

@JaysonMinard Rogerio là tác giả của jmockit – Novaterata

0

Chúng tôi đã thử nghiệm một chút và thấy rằng bạn có thể xác định chức năng đặc biệt như thế này:

fun uninitialized<T>() = null as T 

và sau đó sử dụng nó như thế này:

[Mocked] val dateTime : LocalDateTime = uninitialized() 

Bạn cũng có thể sử dụng nó thay vì Matchers.any() cho cùng một hiệu ứng. Chúng tôi sẽ xem xét thêm nó vào trình biên dịch hoặc thư viện chuẩn.

+0

Cú pháp cho chú thích đã thay đổi, trong ví dụ trên '[Đã bỏ qua]' bây giờ sẽ là '@ Mocked' –

Các vấn đề liên quan