如何模拟从类级别对象调用的方法

我正在为 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的方法,而是执行实际的调用。


HUWWW
浏览 63回答 1
1回答

米琪卡哇伊

模拟类的初始化,以便在执行测试时使用模拟@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 允许模拟构造新对象并不意味着我们应该这样做。如果遵循正确的设计原则,那么确实不需要这样的黑客攻击。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java