3 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個(gè)贊
對(duì)于將來,我會(huì)推薦伊蘭·哈雷爾(Eran Harel)的答案(將new工廠搬遷到可以嘲笑的工廠)。但是,如果您不想更改原始源代碼,請使用非常方便且獨(dú)特的功能:spies。從文檔中:
您可以創(chuàng)建真實(shí)對(duì)象的間諜。當(dāng)您使用間諜時(shí),將調(diào)用實(shí)際方法(除非對(duì)方法進(jìn)行了加注)。
真正的間諜應(yīng)該小心謹(jǐn)慎地使用,例如在處理遺留代碼時(shí)。
在您的情況下,您應(yīng)該寫:
TestedClass tc = spy(new TestedClass());
LoginContext lcMock = mock(LoginContext.class);
when(tc.login(anyString(), anyString())).thenReturn(lcMock);

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超8個(gè)贊
我全力支持Eran Harel的解決方案,在不可能的情況下,Tomasz Nurkiewicz的間諜建議是極好的。但是,值得注意的是,在某些情況下都不適用。例如,如果該login方法有點(diǎn)“騙子”:
public class TestedClass {
public LoginContext login(String user, String password) {
LoginContext lc = new LoginContext("login", callbackHandler);
lc.doThis();
lc.doThat();
}
}
...這是舊代碼,無法重構(gòu)以提取新的初始化LoginContext為其自己的方法并應(yīng)用上述解決方案之一。
為了完整起見,值得一提的是第三種技術(shù)- 在調(diào)用運(yùn)算符時(shí)使用PowerMock注入模擬對(duì)象new。但是,PowerMock并不是靈丹妙藥。它通過在其模擬的類上應(yīng)用字節(jié)碼操作來工作,如果所測試的類采用字節(jié)碼操作或反射,并且至少從我的個(gè)人經(jīng)驗(yàn)出發(fā),已知該類會(huì)給測試帶來性能損失,那么這可能是狡猾的實(shí)踐。再說一次,如果沒有其他選擇,則唯一的選擇必須是好的選擇:
@RunWith(PowerMockRunner.class)
@PrepareForTest(TestedClass.class)
public class TestedClassTest {
@Test
public void testLogin() {
LoginContext lcMock = mock(LoginContext.class);
whenNew(LoginContext.class).withArguments(anyString(), anyString()).thenReturn(lcMock);
TestedClass tc = new TestedClass();
tc.login ("something", "something else");
// test the login's logic
}
}

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超8個(gè)贊
您可以使用工廠來創(chuàng)建登錄上下文。然后,您可以模擬工廠并返回您想要進(jìn)行測試的任何內(nèi)容。
public class TestedClass {
private final LoginContextFactory loginContextFactory;
public TestedClass(final LoginContextFactory loginContextFactory) {
this.loginContextFactory = loginContextFactory;
}
public LoginContext login(String user, String password) {
LoginContext lc = loginContextFactory.createLoginContext();
}
}
public interface LoginContextFactory {
public LoginContext createLoginContext();
}
添加回答
舉報(bào)