[英]Mocking internal instantiated object
我正在編寫一個測試類來測試我的'ImporterService'類。 此服務讀取InputStream並從其數據創建Object。 Object(在本例中為Builder類)在“ImporterService”類中實例化。 要測試我的'ImporterService'類,我需要驗證Builder類的調用。 為此,我想使用Mocking框架,但是如何在'ImporterService'之外創建'Builder'對象的模擬實例?
我的'ImporterService'類的方法如下所示:
public Builder importFrom(BufferedReader reader) throws IOException {
String someValue = readFrom(reader);
Builder builder = new Builder(); // I need to mock this Builder object...
builder.someMethod(someValue); // to see of a method is called with the expected value
}
我正在考慮將Builder類的創建移動到受保護的方法中,我可以在測試設置時覆蓋它。 但是這個解決方案對我來說似乎並不是很好,因為'ImporterService'類正在泄漏一些內部邏輯,並且可以通過我不想要的其他類來覆蓋該方法。
如果您使用任何依賴注入庫(如Spring),您可以將模擬對象而不是構建器注入ImporterService類。 或者你可以用對工廠的調用替換對構造函數的調用,並使用工廠,它會在測試代碼中返回模擬。
是的,您可以按照建議或者:
創建一個Factory類,在其中創建Builder
對象並將其分配給reader類。 在您的單元測試中,模擬此工廠並強制它構建您選擇的構建Builder
,您可以在單元測試中檢查方法調用。
以下是使用EasyMock顯示如何實現此目的的示例:
public class Reader{
private BuilderFactory factory = new BuilderFactory(); // Use production factory by default
public Builder importFrom(BufferedReader reader) throws IOException {
String someValue = readFrom(reader);
Builder builder = factory.buildBuilder();
builder.someMethod(someValue); // to see of a method is called with the expected value
}
}
在您的單元測試中,您執行以下操作:
Reader classUnderTest = new Reader();
BuilderFactory fakeFactory = EasyMock.createNiceMock(BuilderFactory.class);
Builder builder = EasyMock.createMock(Builder.class);
EasyMock.expect(fakeFactory.buildBuilder()).andReturn(builder);
builder.someMethod("value here");
EasyMock.expectLastCall().once();
EasyMock.replay(fakeFactory, builder);
classUnderTest.importFrom(bufferReader);
// Very that all calls were correctly performed on the builder
EasyMock.verify(builder);
假設您正在使用jMockt(我推薦這個模擬框架),您將能夠執行以下操作:
@Test
public void testFoo(@Mocked Builder builder) {
new Expectations() {
{
new Builder();
returns(builder);
builder.setSomemethod()
...
}
};
assertSame(builder,impoertesService.importFrom(...));
}
一些模擬框架(如PowerMock)可以模擬對象的構造。
您可以將功能簽名更改為以下內容:
public Builder importFrom(BufferedReader reader, Builder builder) throws IOException {
通過這樣做,您可以從您的測試用例傳遞任何虛擬實現。 這是依賴注入的一種方式。
依賴注入的想法是要求所有依賴項,如果類/函數執行此操作,則代碼變得高度可測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.