2012-03-14 17 views
22

Tôi muốn giả lập một biến cuối cùng tĩnh cũng như giả lập một lớp i18n bằng cách sử dụng JUnit, EasyMock hoặc PowerMock. Làm thế nào để làm điều đó?Làm thế nào để thử một biến cuối cùng tĩnh bằng cách sử dụng JUnit, EasyMock hoặc PowerMock

+0

Có thể trùng lặp của [Mock private static final field bằng mockito hoặc Jmockit] (http://stackoverflow.com/questions/30703149/mock-private-static-final-field-using-mockito-or-jmockit) – kecso

Trả lời

36

Có điều gì đó giống như chế nhạo một biến không? Tôi sẽ gọi đó là chuyển nhượng lại. Tôi không nghĩ rằng EasyMock hoặc PowerMock sẽ cung cấp cho bạn một cách dễ dàng để gán lại trường static final (có vẻ như trường hợp sử dụng lạ).

Nếu bạn muốn làm điều đó có thể có điều gì đó sai với thiết kế của bạn: tránh static final (hoặc nhiều hằng số chung chung hơn) nếu bạn biết một biến có thể có giá trị khác, ngay cả đối với mục đích thử nghiệm.

Anyways, bạn có thể đạt được điều đó bằng phản xạ (từ: Using reflection to change static final File.separatorChar for unit testing?):

static void setFinalStatic(Field field, Object newValue) throws Exception { 
    field.setAccessible(true); 

    // remove final modifier from field 
    Field modifiersField = Field.class.getDeclaredField("modifiers"); 
    modifiersField.setAccessible(true); 
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 

    field.set(null, newValue); 
} 

Sử dụng nó như sau:

setFinalStatic(MyClass.class.getField("myField"), "newValue"); // For a String 

Đừng quên để thiết lập lại lĩnh vực này với giá trị ban đầu của nó khi rách xuống.

+4

Bất kỳ ai sử dụng điều này nên nhớ rằng trình biên dịch java có thể nội tuyến hằng số và do đó mã có thể không thực sự truy cập các trường cuối cùng khác (nên làm việc cho File.separatorChar vì hằng số sẽ vô dụng khi được inlined). Điều này được mô tả trong [câu hỏi này] (http://stackoverflow.com/questions/5173372/java-static-final-values-replaced-in-code-when-compiling) –

+0

Nếu tôi biết biến chỉ có giá trị khác trong thử nghiệm đơn vị, phương pháp tiếp cận được đề xuất là gì? – Sharif

5

Có thể thực hiện việc kết hợp các tính năng PowerMock. Giả mạo tĩnh bằng cách sử dụng chú thích @PrepareForTest({...}), chế nhạo trường của bạn (Tôi đang sử dụng Mockito.mock(...), nhưng bạn có thể sử dụng cấu trúc EasyMock tương đương) và sau đó đặt giá trị của bạn bằng cách sử dụng phương thức WhiteBox.setInternalState(...). Lưu ý rằng điều này sẽ hoạt động ngay cả khi biến của bạn là private.

Xem liên kết này cho một ví dụ mở rộng: http://codyaray.com/2012/05/mocking-static-java-util-logger-with-easymocks-powermock-extension

+1

Lưu ý - liên kết "ví dụ mở rộng" đề cập đến việc mô phỏng trường ** tĩnh **, không phải trường ** ** tĩnh cuối cùng như được đề cập trong câu hỏi. –

-1

https://github.com/zhangyanwei/staticmock

  1. StaticMockito.enhanceClass ("xxx.Utility");
  2. StaticMockito.initMock (Utility.class);
  3. khi (Utility.toClientId (clientName)). ThenReturn ("name"); xác minh (mocker (Utility.class)). ToClientId (tên máy khách);