如何使用 `when/then` mockito 调用具有相同参数的另一个方法
How to call another method with same arguments using `when/then` mockito
我有以下设置:
class Foo{
public Foo addDate(String str, Date d){
.....
}
public Foo addString(String str){
.....
}
}
class Bar{
private Foo foo;
public void bar(){
foo.addDate(x, x);
}
}
class testBar{
//test bar()
}
在为上述用途编写测试用例时,如何在调用 addDate
时使用 when/then 来调用 addString
但使用相同的参数。
是否可以使用 mock 或 spy 这样的东西?
when(foo.addDate("myString", any())).thenReturn(foo.addString("myString"));
您可以使用 thenAnswer
,您可以在其中编写一个将 Answer
对象作为参数的 lambda,您可以在其中提取对 addDate
:[=15 的调用的参数=]
when(foo.addDate(eq("myString"), any()))
.thenAnswer(answer ->
foo.addString(answer.getArgument(0)));
查看文档 here。
When writing a test case for the usage of the above, how can I use when/then to call addString whenever addDate is called but using the same argument.
我不确定你上面的意思,所以我决定用一个工作示例来说明我遇到的情况,评论中是每个测试的系统输出:
public class TestIt {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
// A bit modified version of your class
public class Foo {
public Foo addDate(String str, Date d) {
System.out.println("addDate(..) should not be called, not mocked?");
return this; // need to return a Foo :)
}
public Foo addString(String str) {
System.out.println("addString(\"" + str + "\")");
return this;
}
}
// To call the real method you need the spy so you can mock only
// methods that needs different functionality
@Spy
private Foo mockFoo;
// answer that uses param in method invocation
private Answer<Foo> answer = invocation ->
mockFoo.addString(invocation.getArgument(0));
// answer that calls with fixed param, not using the invocation
private Answer<Foo> staticAnswer = invocation ->
mockFoo.addString("myString");
@Test
public void testAnswer() {
System.out.println("testAnswer");
doAnswer(answer).when(mockFoo).addDate(any(String.class), any(Date.class));
mockFoo.addDate("add me", new Date());
// testAnswer
// addString("add me")
}
@Test
public void testStaticAnswer() {
System.out.println("testStaticAnswer");
doAnswer(staticAnswer).when(mockFoo).addDate(any(String.class), any(Date.class));
mockFoo.addDate("add me", new Date());
// testStaticAnswer
// addString("myString")
}
@Test
public void testMyString() { // same as Ruben's answer, only react when myString
System.out.println("testMyString");
doAnswer(answer).when(mockFoo).addDate(eq("myString"), any(Date.class));
mockFoo.addDate("add me", new Date());
mockFoo.addDate("myString", new Date());
// testMyString
// addDate(..) should not be called, not mocked?
// addString("myString")
}
}
我有以下设置:
class Foo{
public Foo addDate(String str, Date d){
.....
}
public Foo addString(String str){
.....
}
}
class Bar{
private Foo foo;
public void bar(){
foo.addDate(x, x);
}
}
class testBar{
//test bar()
}
在为上述用途编写测试用例时,如何在调用 addDate
时使用 when/then 来调用 addString
但使用相同的参数。
是否可以使用 mock 或 spy 这样的东西?
when(foo.addDate("myString", any())).thenReturn(foo.addString("myString"));
您可以使用 thenAnswer
,您可以在其中编写一个将 Answer
对象作为参数的 lambda,您可以在其中提取对 addDate
:[=15 的调用的参数=]
when(foo.addDate(eq("myString"), any()))
.thenAnswer(answer ->
foo.addString(answer.getArgument(0)));
查看文档 here。
When writing a test case for the usage of the above, how can I use when/then to call addString whenever addDate is called but using the same argument.
我不确定你上面的意思,所以我决定用一个工作示例来说明我遇到的情况,评论中是每个测试的系统输出:
public class TestIt {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
// A bit modified version of your class
public class Foo {
public Foo addDate(String str, Date d) {
System.out.println("addDate(..) should not be called, not mocked?");
return this; // need to return a Foo :)
}
public Foo addString(String str) {
System.out.println("addString(\"" + str + "\")");
return this;
}
}
// To call the real method you need the spy so you can mock only
// methods that needs different functionality
@Spy
private Foo mockFoo;
// answer that uses param in method invocation
private Answer<Foo> answer = invocation ->
mockFoo.addString(invocation.getArgument(0));
// answer that calls with fixed param, not using the invocation
private Answer<Foo> staticAnswer = invocation ->
mockFoo.addString("myString");
@Test
public void testAnswer() {
System.out.println("testAnswer");
doAnswer(answer).when(mockFoo).addDate(any(String.class), any(Date.class));
mockFoo.addDate("add me", new Date());
// testAnswer
// addString("add me")
}
@Test
public void testStaticAnswer() {
System.out.println("testStaticAnswer");
doAnswer(staticAnswer).when(mockFoo).addDate(any(String.class), any(Date.class));
mockFoo.addDate("add me", new Date());
// testStaticAnswer
// addString("myString")
}
@Test
public void testMyString() { // same as Ruben's answer, only react when myString
System.out.println("testMyString");
doAnswer(answer).when(mockFoo).addDate(eq("myString"), any(Date.class));
mockFoo.addDate("add me", new Date());
mockFoo.addDate("myString", new Date());
// testMyString
// addDate(..) should not be called, not mocked?
// addString("myString")
}
}