2015-06-08 24 views
29

Tôi đang sử dụng private static thức lĩnh vực Logger trong lớp học của tôi và tôi muốn LOGGER.isInfoEnabled() phương pháp để trở sai. Làm thế nào tôi có thể thử các lĩnh vực thức tĩnh bằng cách sử dụng Mockito hoặc jMockitMock private static thức lĩnh vực sử dụng Mockito hoặc Jmockit

lớp của tôi là:

import org.slf4j.Logger; 
    import org.slf4j.LoggerFactory; 

    public class Class1 { 

    private static final Logger LOGGER = LoggerFactory.getLogger(Class1.class); 

    public boolean demoMethod() { 
     System.out.println("Demo started"); 
     if (LOGGER.isInfoEnabled()) { 
     System.out.println("@@@@@@@@@@@@@@ ------- info is enabled"); 
     } else { 
     System.out.println("info is disabled"); 
     } 
     return LOGGER.isInfoEnabled(); 
    } 
    } 

và junit của nó là:

import mockit.Mocked; 
import mockit.NonStrictExpectations; 
import org.mockito.InjectMocks; 
import org.mockito.MockitoAnnotations; 
import org.slf4j.Logger; 
import org.testng.annotations.BeforeMethod; 
import org.testng.annotations.Test; 

import static org.testng.Assert.*; 
import com.source.Class1; 

public class MyTest { 

    @InjectMocks 
    Class1 cls1; 

    @BeforeMethod 
    public void initMocks() { 
    MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    public void test(@Mocked final Logger LOGGER) { 

    new NonStrictExpectations() { 
     { 
     LOGGER.isInfoEnabled(); 
     result = false; 
     } 
    }; 
    assertFalse(cls1.demoMethod()); 
    } 
} 

khi tôi chạy nó kết quả là:

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running com.test.MyTest 
Configuring TestNG with: TestNG652Configurator 
Demo started 
@@@@@@@@@@@@@@ ------- info is enabled 
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.9 sec <<< FAILURE! - in com.test.MyTest 
test(com.test.MyTest) Time elapsed: 0.168 sec <<< FAILURE! 
java.lang.AssertionError: expected [false] but found [true] 
     at com.test.MyTest.test(MyTest.java:35) 


Results : 

Failed tests: 
    MyTest.test:35 expected [false] but found [true] 

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0 

[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD FAILURE 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 9.899s 
[INFO] Finished at: Mon Jun 08 12:35:36 IST 2015 
[INFO] Final Memory: 16M/166M 
[INFO] ------------------------------------------------------------------------ 
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project JMockDemo: The 
re are test failures. 
[ERROR] 
[ERROR] Please refer to D:\perfoce_code\workspace_kepler\JMockDemo\target\surefire-reports for the individual test results. 
[ERROR] -> [Help 1] 
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. 
[ERROR] Re-run Maven using the -X switch to enable full debug logging. 
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles: 
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException 

Tôi mới dùng jmockit và tôi muốn trường hợp trên junit của mình chạy thành công. Và tôi phải sử dụng JMockit hoặc mockito, không thể sử dụng Powermockito. Xin vui lòng giúp đỡ.

+0

Bạn có thể tạo một phương pháp setter cho các thành phần và thiết lập một logger giả trong khi thử nghiệm. –

+0

Có nó đang làm việc theo cách đó, nhưng tôi phải làm cho logger không phải cuối cùng và cũng thêm một phương thức setter. Không có cách nào để làm điều đó mà không thay đổi lớp thực tế. –

+3

Chỉ cần thay đổi '@Mocked Logger' thành' @Capturing Logger', nó sẽ hoạt động. –

Trả lời

35

Một cách là sử dụng phản ánh thoát khỏi final modifier từ lĩnh vực này và sau đó thay thế lĩnh vực LOGGER với chế giễu một

public class Class1Test { 
    @Test 
    public void test() throws Exception { 
     Logger logger = Mockito.mock(Logger.class); 
     Mockito.when(logger.isInfoEnabled()).thenReturn(false); 
     setFinalStatic(Class1.class.getDeclaredField("LOGGER"), logger); 
     Class1 cls1 = new Class1(); 
     assertFalse(cls1.demoMethod()); 
    } 

    static void setFinalStatic(Field field, Object newValue) throws Exception { 
     field.setAccessible(true);   
     Field modifiersField = Field.class.getDeclaredField("modifiers"); 
     modifiersField.setAccessible(true); 
     modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 
     field.set(null, newValue); 
    } 
} 
+0

Wow tuyệt vời, đây là giải pháp tôi đang tìm kiếm, cảm ơn bạn rất nhiều :-) –

+0

Tại sao bạn làm cho phương thức setFinalStatic tĩnh, có lý do cụ thể nào không? –

+9

Điều này rất nguy hiểm vì nó làm thay đổi cá thể tĩnh cho toàn bộ ClassLoader của bạn. Bất kỳ bài kiểm tra/lớp học tiếp theo nào sẽ có trường hợp giả lập của trình ghi nhật ký đó. Điều này cũng không nên được sử dụng khi chạy thử nghiệm song song. Điều này có thể dẫn đến các vấn đề đa luồng nghiêm trọng trong các thử nghiệm của bạn, hãy thận trọng về điều đó. –

1

Tôi nghĩ rằng mockito hoặc jMockit không thể giả lập các lớp học cuối cùng tĩnh khi họ cố gắng ghi đè lên các phương pháp trong khi kiểm tra đơn vị. Tuy nhiên, powerMockito có thể vì nó sử dụng Reflection và giả lập lớp/phương thức cuối cùng tĩnh.

+1

Bạn không thể ghi đè các phương thức cuối cùng .. Bạn chỉ có thể làm điều đó nếu bạn sử dụng sự phản chiếu. –

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