java 如何模拟方法内部的调用

093gszye  于 2023-04-28  发布在  Java
关注(0)|答案(2)|浏览(130)

我是新来的。我想通过使用模拟的ClassD参数调用handle()方法来对以下代码进行单元测试:

public class ClassA{

    @Autowired
    Bean1 bean1;

    public ClassC handle(ClassD d) {

        ClassC c = bean1.method1(d);
        return methodA(c);
    }
}

但是我不想实际调用method1()。所以我写了下面的testcase:

@ExtendWith(MockitoExtension.class)
ClassATest{
@Mock 
ClassD d;
@Mock
Bean1 bean1;

@Mock
ClassC c;

@BeforeEach
public void setUp() throws Exception {
    sut = new ClassA();
}

@Test
handleTest(){
    Mockito.lenient().when(bean1.method1(d)).thenReturn(c);
    sut.handle(d);
    Mockito.verify(bean1, times(1)).method1(any());
 }
}

我得到错误:

ClassATest > handleTest() FAILED
    Wanted but not invoked:
    bean1.method1(
        <any>
    );

我说错什么了吗?有没有办法让我和莫奇托一起做这个?

9gm1akwq

9gm1akwq1#

我说错什么了吗?
你在测试中模拟了bean1,但你没有在对象sut上设置它-它有自己的内部bean1,这不是一个模拟。
有没有办法让我和莫奇托一起做这个?
您可以将mock传递给类,以确保它是调用方法的示例:

public class ClassA{

    @Autowired
    Bean1 bean1;

    // Constructor that explicitly sets the bean - for testing
    public ClassA(Bean1 theBean) {
       this.bean1 = theBean;
    }

    public ClassC handle(ClassD d) {

        ClassC c = bean1.method1(d);
        return methodA(c);
    }
}

然后你的测试通过了mock:

@ExtendWith(MockitoExtension.class)
ClassATest{
@Mock 
ClassD d;
@Mock
Bean1 bean1;

@Mock
ClassC c;

@BeforeEach
public void setUp() throws Exception {
    sut = new ClassA(bean1); // PASS THE MOCK THROUGH
}

@Test
handleTest(){
    Mockito.lenient().when(bean1.method1(d)).thenReturn(c);
    sut.handle(d); // NOW WHEN THIS IS CALLED, IT'S USING A MOCK
    Mockito.verify(bean1, times(1)).method1(any());
 }
}
c8ib6hqw

c8ib6hqw2#

问题是lenient()。Lenient允许在不验证调用的情况下对方法进行存根处理。这就是为什么verify()不检查任何东西。对于我来说,你需要删除lenient()并使用常规的when()方法:

when(bean1.method1(d)).thenReturn(c);
        sut.handle(d);
        verify(bean1, times(1)).method1(d);

不要初始化ClassA。只需删除@beforeEach setUp并编写以下代码即可

@InjectMocks
ClassA sut;

相关问题