java—mockito的argumentcaptor示例

ca1c2owp  于 2021-07-13  发布在  Java
关注(0)|答案(4)|浏览(344)

谁能给我举个例子说明如何使用 org.mockito.ArgumentCaptor 类以及它与mockito提供的简单匹配器的区别。
我阅读了提供的mockito文件,但这些文件没有说明清楚,没有人能够解释清楚。

zqdjd7g9

zqdjd7g91#

我同意@fge所说的,更多。让我们看一个例子。假设你有一个方法:

class A {
    public void foo(OtherClass other) {
        SomeData data = new SomeData("Some inner data");
        other.doSomething(data);
    }
}

现在,如果您想检查内部数据,可以使用captor:

// Create a mock of the OtherClass
OtherClass other = mock(OtherClass.class);

// Run the foo method with the mock
new A().foo(other);

// Capture the argument of the doSomething function
ArgumentCaptor<SomeData> captor = ArgumentCaptor.forClass(SomeData.class);
verify(other, times(1)).doSomething(captor.capture());

// Assert the argument
SomeData actual = captor.getValue();
assertEquals("Some inner data", actual.innerData);
cpjpxq1n

cpjpxq1n2#

两个主要区别是:
当你捕捉到一个参数时,你就可以对这个参数进行更详细的测试,并且使用更明显的代码;
ArgumentCaptor 可以捕获多次。
为了说明后者,假设你有:

final ArgumentCaptor<Foo> captor = ArgumentCaptor.forClass(Foo.class);

verify(x, times(4)).someMethod(captor.capture()); // for instance

然后捕获者将允许您访问所有4个参数,然后您可以分别对这些参数执行Assert。
事实上,由于 VerificationMode 不限于固定的调用次数;在任何情况下,如果你愿意的话,俘虏者会让你接触到所有的人。
这样做还有一个好处,即这样的测试(imho)比实现自己的测试要容易得多 ArgumentMatcher 特别是如果你把mockito和assertj结合起来。
哦,请考虑使用testng而不是junit。

bfhwhh0e

bfhwhh0e3#

进行全面检查的步骤如下:
准备好俘虏:

ArgumentCaptor<SomeArgumentClass> someArgumentCaptor = ArgumentCaptor.forClass(SomeArgumentClass.class);

验证对dependent-on-component(被测主体的合作者)的调用次数(1)是否为默认值,因此需要添加它。

verify(dependentOnComponent, times(1)).send(someArgumentCaptor.capture());

时间(1)是默认值,因此不需要添加它。
将参数传递给合作者

SomeArgumentClass someArgument = messageCaptor.getValue();

someargument可用于Assert

tyu7yeag

tyu7yeag4#

这里我给你一个回调方法的恰当例子。所以假设我们有一个类似method login()的方法:

public void login() {
    loginService = new LoginService();
    loginService.login(loginProvider, new LoginListener() {
        @Override
        public void onLoginSuccess() {
            loginService.getresult(true);
        }

        @Override
        public void onLoginFaliure() {
            loginService.getresult(false);

        }
    });
    System.out.print("@@##### get called");
}

我还将所有helper类放在这里,以使示例更清楚:loginservice类

public class LoginService implements Login.getresult{
public void login(LoginProvider loginProvider,LoginListener callback){

    String username  = loginProvider.getUsername();
    String pwd  = loginProvider.getPassword();
    if(username != null && pwd != null){
        callback.onLoginSuccess();
    }else{
        callback.onLoginFaliure();
    }

}

@Override
public void getresult(boolean value) {
    System.out.print("login success"+value);
}}

我们的listener loginlistener为:

interface LoginListener {
void onLoginSuccess();

void onLoginFaliure();

}
现在我只想测试login类的login()方法

@Test
public void loginTest() throws Exception {
    LoginService service = mock(LoginService.class);
    LoginProvider provider = mock(LoginProvider.class);
    whenNew(LoginProvider.class).withNoArguments().thenReturn(provider);
    whenNew(LoginService.class).withNoArguments().thenReturn(service);
    when(provider.getPassword()).thenReturn("pwd");
    when(provider.getUsername()).thenReturn("username");
    login.getLoginDetail("username","password");

    verify(provider).setPassword("password");
    verify(provider).setUsername("username");

    verify(service).login(eq(provider),captor.capture());

    LoginListener listener = captor.getValue();

    listener.onLoginSuccess();

    verify(service).getresult(true);

也别忘了在测试类上面添加注解

@RunWith(PowerMockRunner.class)
@PrepareForTest(Login.class)

相关问题