你有3種可能性來解決這個問題:
抽象工廠:而不是使用一個靜態方法,用一個具體的工廠類:
public abstract class AppleFactory {
public Apple createInstance(final String str);
}
public class AppleFactoryImpl implements AppleFactory {
public Apple createInstance(final String str) { // Implementation }
}
在您的測試類,模擬工廠:
@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
@Mock
private AppleFactory appleFactoryMock;
@Mock
private Apple appleMock;
@InjectMocks
MyClass myClass;
@Before
public void setup() {
when(appleFactoryMock.createInstance(Matchers.anyString()).thenReturn(appleMock);
}
@Test
public void myMethod(){
...
...
...
}
}
PowerMock:使用PowerMock創建STA的模擬抽動法。看看my answer to a relevant question看看它是如何完成的。
可測試類:讓Apple
創建包裹在一個protected
方法,並創建一個測試類中的覆蓋:
public class MyClass {
private Apple apple;
public void myMethod() {
apple = createApple();
....
....
....
}
protected Apple createApple() {
return AppleFactory.createInstance(someStringVariable);
}
}
@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
@Mock
private Apple appleMock;
@InjectMocks
MyClass myClass;
@Test
public void myMethod(){
...
...
...
}
private class TestableMyClass extends MyClass {
@Override
public void createApple() {
return appleMock;
}
}
}
當然,在您的測試類,你應該測試TestableMyClass
而不是MyClass
。
我會告訴你在每個方法我認爲:
抽象工廠方法是最好的一個 - 這是一個明確的設計,隱藏實現細節
可測試類 - 是需要最小變化的第二個選項
PowerMock
選項是我最不喜歡的 - 不要去尋求更好的設計,而是忽略並隱藏 你的問題。但這仍然是一個有效的選擇。
來源
2014-02-19 12:01:18
Avi
太棒了,謝謝。我必須在我的情況下使用Mockito,所以我將使用Abstract Factory或TestableClass選項。 –
@saravana_pc - 我添加了我的排名問題。儘管如此,你可以使用'mockito'進行功能模擬。您可以使用它們的等價方法(因此,在實現抽象工廠模式時,可以不使用@ @ Mock和@InjectMock'(因此您可以擺脫「@RunWith(MockitoJUnitRunner.class)」聲明) – Avi
,更合適嗎? –