2012-08-23 31 views
6

Tôi đang cố gắng thực hiện cuộc gọi đến phương thức cuối cùng ResourceBundle.getString(). Với PowerMock 1.4.12 và EasyMock 3.1, cuộc gọi không bị nhạo báng; thay vào đó, phương thức "thực" được gọi.Mocking phương thức cuối cùng với PowerMock + EasyMock

lớp thử nghiệm của tôi:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ResourceBundle.class) 
public class TestSuite { 
    @Before 
    public void setUp() throws Exception { 
     ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class); 
     expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue"); 
     PowerMock.replay(resourceBundleMock); 

     beanBeingTested.setMessages(resourceBundleMock); 
    } 
    ... 
} 

Mã trong BeanBeingTested:

private ResourceBundle messages; 
... 
String label = messages.getString(BundleConstants.QUEUE); 

Thông báo lỗi:

java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue 
at java.util.ResourceBundle.getObject(ResourceBundle.java:384) 
at java.util.ResourceBundle.getString(ResourceBundle.java:344) 
at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87) 

Khi tôi bước qua trường hợp kiểm tra, trình gỡ lỗi cho thấy các loại beanBeingTested.messages là "EasyMock cho lớp java.util.ResourceBundle", vì vậy, mô phỏng được chèn vào đúng ectly. (Ngoài ra, không có lỗi khi gọi tới số getString() trong cuộc gọi expect() khi thiết lập).

Với một mô hình đơn giản thay vì một mô hình đẹp, tôi nhận được lỗi sau:

java.lang.AssertionError: 
    Unexpected method call handleGetObject("Queue"): 
    getString("Queue"): expected: 1, actual: 0 

Bất kỳ ý tưởng những gì tôi đang làm sai?

Cảm ơn.

Trả lời

0

Tại sao lại làm nhạo cuộc gọi đến gói tài nguyên? Nói chung, tôi cố gắng tránh chế nhạo các loại hạt và bu lông của java, chẳng hạn như ArrayList, Date, vv. Gói tài nguyên (và MessageFormat.format()) nhiều hơn hoặc ít hơn thuộc cùng một loại cho tôi. Họ thường hoạt động trên dây là nguyên tắc cơ bản, và nếu những điều này bị hỏng hoặc thay đổi hành vi của họ đủ để phá vỡ một thử nghiệm đó chắc chắn là điều tôi muốn biết :)

Chỉ cần để cho họ lấy chuỗi (có lẽ là về được đặt trong giao diện người dùng, có lẽ sau. Đừng bận tâm để khẳng định giá trị được trả về vì bạn không muốn chỉnh sửa cho nhóm để phá vỡ thử nghiệm của bạn.Nếu chuỗi được đặt trên thành phần giao diện người dùng giả, đây là một vị trí tốt cho anyObject (String.class) thể hiện chính xác thực tế bạn (có thể) không thực sự quan tâm đến chuỗi cụ thể được hiển thị

Tôi cũng coi đó là một lợi ích khi thử nghiệm không thành công do thiếu khóa tin nhắn. biết

3

Bạn đang tạo một ví dụ bằng EasyMock. Thay vào đó, khi làm việc với các phương thức tĩnh, bạn phải giả lập lớp (sử dụng PowerMock).

Nó sẽ làm việc như thế (thử nghiệm với EasyMock 3.0 và PowerMock 1.5, mặc dù):

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ResourceBundle.class) 
public class TestSuite { 
    @Before 
    public void setUp() throws Exception { 
     // mock the class for one method only 
     PowerMock.mockStaticNice(ResourceBundle.class, "getString"); 

     // define mock-behaviour on the class, when calling the static method 
     expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue"); 

     // start the engine 
     PowerMock.replayAll(); 
    } 
} 

(Tôi biết câu hỏi này là một vài tháng tuổi, nhưng nó có thể giúp đỡ người khác, mặc dù)

+0

Tôi cũng đang đối mặt với cùng một vấn đề.Nhưng điều này vẫn không giúp được gì. Bạn đang đề cập đến phương pháp cuối cùng chỉ hoặc phương pháp tĩnh? – Siddharth

+0

@Siddharth {{PowerMock.mockStaticNice()}} mô phỏng một phương thức tĩnh của một lớp, nhưng để phần còn lại của các phương thức không bị ảnh hưởng. Nếu chủ đề này không giúp bạn, bạn nên tạo một câu hỏi mới, bởi vì có vẻ như bạn đang gặp phải các vấn đề khác nhau. – Andy

+0

Cảm ơn bạn đã trả lời @Andy. Nhưng chủ đề của chủ đề này nói về phương thức cuối cùng nhưng bạn đang nói về phương pháp tĩnh. Tui bỏ lỡ điều gì vậy? Vấn đề của tôi là có phương thức "public final void" mà tôi đang cố gắng giả lập và thử nghiệm đang gọi phương thức thực tế thay vì giả lập. Vấn đề trên có khác với vấn đề tôi đang nói không? Xin lỗi nếu tôi bị mất một số điểm. – Siddharth

1

Thử sử dụng:

@PrepareForTest({ResourceBundle.class, BeanBeingTested.class}) 

với chỉ ResourceBundle trong PrepareForTest các mô hình sẽ làm việc khi gọi trực tiếp từ phương pháp kiểm tra đơn vị của bạn, nhưng khi gọi từ BeanBeingTested bạn g et phương pháp thực được sử dụng.

Tài liệu Powermock thiếu trong lĩnh vực này.

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