Ujj*_*wal 111 java junit unit-testing mockito
任何人都可以请给我一个例子,说明什么是org.mockito.ArgumentCaptor类的使用,以及它与mockito提供的简单匹配器有何不同.
我阅读了所提供的mockito文档,但这些文档没有清楚地说明,也没有能够清楚地解释它.
Sla*_*lny 148
我同意@fge所说的更多内容.让我们看一下例子.考虑一下你有一个方法:
class A {
public void foo(OtherClass other) {
SomeData data = new SomeData("Some inner data");
other.doSomething(data);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您想检查内部数据,可以使用捕获器:
// 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);
Run Code Online (Sandbox Code Playgroud)
fge*_*fge 29
两个主要区别是:
ArgumentCaptor可以捕捉更比一次.为了说明后者,请说:
final ArgumentCaptor<Foo> captor = ArgumentCaptor.forClass(Foo.class);
verify(x, times(4)).someMethod(captor.capture()); // for instance
Run Code Online (Sandbox Code Playgroud)
然后,捕获者将能够访问所有4个参数,然后您可以单独执行断言.
事实上这个或任意数量的参数,因为a VerificationMode不限于固定数量的调用; 无论如何,如果您愿意,捕获者将允许您访问所有这些.
这样做的好处是,这些测试(imho)比实现自己ArgumentMatcher的测试更容易编写- 特别是如果你将mockito与assertj结合起来.
哦,请考虑使用TestNG而不是JUnit.
小智 11
我创建了这个示例,它模拟一个非常简单的服务,该服务使用存储库来保存字符串(无依赖项注入,无实体),只是为了快速教授 ArgumentCaptor。
3个类:PersonService、PersonRepository和PersonServiceTest(包略)
public class PersonService {
private PersonRepository personRepository;
public void setPersonRepository(final PersonRepository personRepository) {
this.personRepository = personRepository;
}
public void savePerson(final String name) {
this.personRepository.save(name.toUpperCase().trim());
}
}
public class PersonRepository {
public void save(final String person) {
System.out.println(".. saving person ..");
}
}
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
class PersonServiceTest {
@Test
void testPersonService() {
// Create the repository mock
final PersonRepository personRepositoryMock = mock(PersonRepository.class);
// Create the service and set the repository mock
final PersonService personService = new PersonService();
personService.setPersonRepository(personRepositoryMock);
// Save a person
personService.savePerson("Mario ");
// Prepare an ArgumentCaptor to capture the value passed to repo.saveMethod
final ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
// Capture the argument passed in the unique method invocation
verify(personRepositoryMock, times(1)).save(captor.capture());
// Check if the captured value is the expected one
final String capturedParameter = captor.getValue();
assertEquals("MARIO", capturedParameter);
}
}
Run Code Online (Sandbox Code Playgroud)
进行全面检查的步骤是:
准备捕获器:
ArgumentCaptor<SomeArgumentClass> someArgumentCaptor = ArgumentCaptor.forClass(SomeArgumentClass.class);
Run Code Online (Sandbox Code Playgroud)
验证对依赖于组件(被测对象的合作者)times(1)的调用是默认值,因此需要添加它。
verify(dependentOnComponent, times(1)).send(someArgumentCaptor.capture());
Run Code Online (Sandbox Code Playgroud)
将参数传递给协作者
SomeArgumentClass someArgument = messageCaptor.getValue();
Run Code Online (Sandbox Code Playgroud)
someArgument可用于断言