問題描述
假設我有這樣的課程:
public class MyClass {
Dao dao;
public String myMethod(Dao d) {
dao = d;
String result = dao.query();
return result;
}
}
我想用 mockito 測試它.所以我創建了一個模擬對象并以這種方式調用該方法進行測試:
I want to test it with mockito. So I create a mock object and I call the method to test in that way:
Dao mock = Mockito.mock(Dao.class);
Mockito.when(mock.myMethod()).thenReturn("ok");
new MyClass().myMethod(mock);
但是,假設我有一個這樣的課程:
But, suppose instead I have a class like that:
public class MyClass {
Dao dao = new Dao();
public String myMethod() {
String result = dao.query();
return result;
}
}
現在我無法將我的模擬作為參數傳遞,那么我將如何測試我的方法?有人可以舉個例子嗎?
Now I cannot pass my mock as an argument, so how I gonna test my method? Can someone show an example?
推薦答案
從根本上說,您試圖用替代實現替換私有字段,這意味著您違反了封裝.您唯一的其他選擇是重組類或方法,使其更適合測試.
Fundamentally, you're trying to replace a private field with an alternative implementation, which means you'd violate encapsulation. Your only other option is to restructure the class or method, to make it better-designed for testing.
評論中有很多簡短的答案,所以我在這里將它們匯總(并添加我自己的幾個)作為社區 Wiki.如果您有任何替代方案,請隨時在此處添加.
There are a lot of short answers in the comments, so I'm aggregating them here (and adding a couple of my own) as Community Wiki. If you have any alternatives, please feel free to add them here.
為相關字段創建一個 setter,或放寬該字段的可見性.
Create a setter for the field in question, or relax the field's visibility.
創建一個采用 DAO 的依賴注入覆蓋或靜態方法,并將公共實例方法委托給它.改為測試更靈活的方法.
Create a dependency-injecting override or static method that takes a DAO, and make the public instance method delegate to it. Test the more-flexible method instead.
public String myMethod() { return myMethod(dao); }
String myMethod(Dao dao) { /* real implementation here */ }
添加構造函數重載或靜態工廠方法來替換私有字段以進行測試.
Add a constructor overload or static factory method that replaces private fields for the sake of testing.
完全構建依賴注入的類.(Sotirios Delimanolis, EJK)
Fully structure the class for dependency injection. (Sotirios Delimanolis, EJK)
請注意,如果您將測試放在同一個 Java 包中(可能在單獨的源代碼樹中),其中一些可以是包私有的以進行測試.在任何情況下,良好的名稱和文檔都有助于明確您的意圖.
Note that some of these can be package-private for testing, if you put your tests in the same Java package (possibly in a separate source tree). In all cases, good names and documentation are helpful to make your intentions clear.
- 使用反射在類中設置私有字段.(kinbiko - 請參閱 answer)
- 使用 PowerMockito 替換
Dao
構造函數與您選擇的模擬.(戴夫·牛頓)
- Use reflection to set private fields in the class. (kinbiko - see answer)
- Use PowerMockito to replace the
Dao
constructor with a mock of your choice. (Dave Newton)
這篇關于當我們無法將模擬對象傳遞給類的實例時如何使用 Mockito的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!