亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何模擬從類級別對象調用的方法

如何模擬從類級別對象調用的方法

HUWWW 2023-10-12 16:44:40
我正在為 A 類編寫單元測試,我想模擬一個方法,但該方法是從類級別對象中良性調用的,我將如何模擬它。讓我用例子來解釋一下正在測試中的 A 級。public class ClassA {    ClassB objectOfB = new ClassB();    public int add(int a, int b) {        int addition = objectOfB.performCalculation(a,b);        return addition;    }}B類,有一些業務邏輯。  public class ClassB {    public int performCalculation(int a, int b) {        int c = a+b;        System.out.println("I am not mocked, I am actual call");        System.out.println("Returning " + c + " From ClassB");        return c;    }  }筆試import static org.junit.Assert.*;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.mockito.Mockito;import org.powermock.core.classloader.annotations.PrepareForTest;import org.powermock.modules.junit4.PowerMockRunner;@RunWith(PowerMockRunner.class)@PrepareForTest({ClassA.class, ClassB.class})public class ClassATest {    @InjectMocks    ClassA objA = new ClassA();    @Test    public void testAddFromClassA() throws Exception {        ClassB objB = Mockito.mock(ClassB.class);        Mockito.when(objB.performCalculation(5, 10)).thenReturn(15);        int result = objA.add(5, 10);        assertEquals(result, 15);    }}測試結果:這個測試是通過的,但它不是模擬ClassB的方法,而是執行實際的調用。
查看完整描述

1 回答

?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

模擬類的初始化,以便在執行測試時使用模擬


@RunWith(PowerMockRunner.class)

@PrepareForTest({ClassA.class}) //prepare the class creating the new instance of ClassB for test, not the ClassB itself.

public class ClassATest {

? ? @Test

? ? public void testAddFromClassA() throws Exception {

? ? ? ? int expected = 15;

? ? ? ? ClassB objB = Mockito.mock(ClassB.class);

? ? ? ? Mockito.when(objB.performCalculation(5, 10)).thenReturn(expected);


? ? ? ? //mocking initialization of ClassB class withing ClassA class

? ? ? ? PowerMockito.whenNew(ClassB.class).withNoArguments().thenReturn(objB);


? ? ? ? ClassA objA = new ClassA();


? ? ? ? //Act

? ? ? ? int actual = objA.add(5, 10);


? ? ? ? //Assert

? ? ? ? assertEquals(expected, actual);

? ? }

}

參考如何模擬新對象的構造

話雖如此,理想情況下目標類應該通過構造函數注入遵循顯式依賴原則


public class ClassA {

? ? final ClassB objectOfB;


? ? public ClassA(ClassB objectOfB) {

? ? ? ? this.objectOfB = objectOfB;

? ? }


? ? public int add(int a, int b) {

? ? ? ? int addition = objectOfB.performCalculation(a,b);

? ? ? ? return addition;

? ? }

}

允許類顯式地聲明執行其設計功能所依賴的內容。


它還允許控制反轉和松散耦合,這使得類更靈活地維護和測試


@RunWith(PowerMockRunner.class)

public class ClassATest {

? ? @Test

? ? public void testAddFromClassA() throws Exception {

? ? ? ? int expected = 15;

? ? ? ? ClassB objB = Mockito.mock(ClassB.class);

? ? ? ? Mockito.when(objB.performCalculation(5, 10)).thenReturn(expected);


? ? ? ? ClassA objA = new ClassA(objB);


? ? ? ? //Act

? ? ? ? int actual = objA.add(5, 10);


? ? ? ? //Assert

? ? ? ? assertEquals(expected, actual);

? ? }

}

僅僅因為 PowerMockito 允許模擬構造新對象并不意味著我們應該這樣做。


如果遵循正確的設計原則,那么確實不需要這樣的黑客攻擊。


查看完整回答
反對 回復 2023-10-12
  • 1 回答
  • 0 關注
  • 153 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號