2016-04-22 14 views
17

Ở đây Utils.java là lớp của tôi được kiểm tra và sau đây là phương thức được gọi trong lớp UtilsTest. Ngay cả khi tôi đang chế giễu phương pháp Log.e như hình dưới đâyLàm thế nào để giả lập phương thức e trong Log

@Before 
    public void setUp() { 
    when(Log.e(any(String.class),any(String.class))).thenReturn(any(Integer.class)); 
      utils = spy(new Utils()); 
    } 

Tôi nhận được ngoại lệ sau

java.lang.RuntimeException: Method e in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details. 
    at android.util.Log.e(Log.java) 
    at com.xxx.demo.utils.UtilsTest.setUp(UtilsTest.java:41) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 

Trả lời

2

Mockito không thử phương pháp tĩnh. Sử dụng PowerMockito trên đầu trang. Here là một ví dụ.

+1

@ user3762991 Bạn cũng cần thay đổi đối sánh của mình. Bạn không thể sử dụng một matcher trong câu lệnh 'thenReturn (...)'. Bạn cần chỉ định giá trị hữu hình. Xem thêm thông tin [ở đây] (https://stackoverflow.com/questions/36771597/mockito-throwing-invaliduseofmatchersexception) – troig

+0

Nếu e, d, v phương pháp không thể được chế giễu, chỉ vì giới hạn này mockito trở nên không sử dụng được? – user3762991

+2

Nếu bạn không thể ăn nĩa, nó có trở thành không sử dụng được không? Nó đơn giản có một mục đích khác. – Antiohia

17

Sử dụng PowerMockito:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Log.class}) 
public class TestsToRun() { 
    @Test 
    public void test() { 
     PowerMockito.mockStatic(Log.class); 
    } 
} 

Và bạn tốt để đi. Lưu ý rằng PowerMockito sẽ không tự động giả lập các phương thức tĩnh kế thừa, vì vậy nếu bạn muốn giả lập một lớp ghi nhật ký tùy chỉnh mở rộng Nhật ký, bạn vẫn phải thử Đăng nhập cho các cuộc gọi như MyCustomLog.e().

+1

Làm thế nào bạn nhận được ** PowerMockRunner ** trong Gradle ?? –

+3

@IgorGanapolsky Xem câu trả lời của tôi [ở đây] (http://stackoverflow.com/a/39172168/5495432). –

4

Sử dụng PowerMockito.

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ClassNameOnWhichTestsAreWritten.class , Log.class}) 
public class TestsOnClass() { 
    @Before 
    public void setup() { 
     PowerMockito.mockStatic(Log.class); 
    } 
    @Test 
    public void Test_1(){ 

    } 
    @Test 
    public void Test_2(){ 

    } 
} 
15

Bạn có thể đặt này vào kịch bản gradle của bạn:

android { 
    ... 
    testOptions { 
     unitTests.returnDefaultValues = true 
    } 
} 

Điều đó sẽ quyết định xem phương pháp unmocked từ android.jar nên ném ngoại lệ hoặc trả lại giá trị mặc định.

+10

* Từ Tài liệu: * ** Thận trọng: ** Việc đặt thuộc tính returnDefaultValues ​​thành true nên được thực hiện cẩn thận. Các giá trị trả về null/zero có thể giới thiệu các phép hồi quy trong các thử nghiệm của bạn, rất khó để gỡ lỗi và có thể cho phép các phép thử không thành công. ** Chỉ sử dụng nó như một phương sách cuối cùng. ** –

19

Điều này hiệu quả đối với tôi. Tôi chỉ sử dụng JUnit và tôi có thể giả lập lớp Logmà không có bất kỳ thư viện nào của bên thứ ba rất dễ dàng. Chỉ cần tạo một tệp Log.java bên trong app/src/test/java/android/util với nội dung:

public class Log { 
    public static int d(String tag, String msg) { 
     System.out.println("DEBUG: " + tag + ": " + msg); 
     return 0; 
    } 

    public static int i(String tag, String msg) { 
     System.out.println("INFO: " + tag + ": " + msg); 
     return 0; 
    } 

    public static int w(String tag, String msg) { 
     System.out.println("WARN: " + tag + ": " + msg); 
     return 0; 
    } 

    public static int e(String tag, String msg) { 
     System.out.println("ERROR: " + tag + ": " + msg); 
     return 0; 
    } 

    // add other methods if required... 
} 
+0

Điều này thật là rực rỡ. Và nó né tránh nhu cầu về PowerMockito. 10/10 – Sipty

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