Java 如何使用'when/then'mockito调用具有相同参数的另一个方法
我有以下设置:Java 如何使用'when/then'mockito调用具有相同参数的另一个方法,java,mockito,Java,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{
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()
}
在编写上述用法的测试用例时,我如何使用When/then调用addString
,只要调用了addDate
,但使用了相同的参数
使用mock或spy可以进行类似的操作吗
when(foo.addDate("myString", any())).thenReturn(foo.addString("myString"));
您可以使用
然后使用Answer
,在这里您可以编写一个lambda,它将Answer
对象作为参数,在这里您可以提取调用addDate
的参数:
when(foo.addDate(eq("myString"), any()))
.thenAnswer(answer ->
foo.addString(answer.getArgument(0)));
查看文档。您可以使用
然后Answer
,在这里您可以编写一个lambda,将Answer
对象作为参数,从中可以提取调用addDate
的参数:
when(foo.addDate(eq("myString"), any()))
.thenAnswer(answer ->
foo.addString(answer.getArgument(0)));
看看这些文件
在编写上述用法的测试用例时,如何使用When/then在调用addDate时调用addString,但使用相同的参数
我不确定上面所说的是什么意思,所以我决定用一个工作示例来介绍我遇到的情况,注释中是每个测试的系统输出:
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")
}
}
公共类测试{
@统治
public MockitoRule MockitoRule=MockitoJUnit.rule();
//您的类的一个稍加修改的版本
公开课Foo{
public Foo addDate(字符串str,日期d){
System.out.println(“不应该调用addDate(..),而不是mock?”);
返回此;//需要返回一个Foo:)
}
公共Foo addString(String str){
System.out.println(“addString(\“”+str+“\”);
归还这个;
}
}
//要调用真正的方法,您需要间谍,这样您只能模拟
//需要不同功能的方法
@间谍
私人Foo mockFoo;
//在方法调用中使用param的答案
私人应答=调用->
mockFoo.addString(invocation.getArgument(0));
//回答使用固定参数的调用,而不是使用调用
私有应答staticAnswer=调用->
mockFoo.addString(“myString”);
@试验
公共无效测试答案(){
System.out.println(“testAnswer”);
doAnswer(answer).when(mockFoo).addDate(any(String.class),any(Date.class));
mockFoo.addDate(“addme”,newdate());
//测试者
//addString(“添加我”)
}
@试验
公共void testStaticAnswer(){
System.out.println(“testStaticAnswer”);
doAnswer(staticAnswer).when(mockFoo).addDate(any(String.class),any(Date.class));
mockFoo.addDate(“addme”,newdate());
//测试静态答案
//addString(“myString”)
}
@试验
public void testMyString(){//与Ruben的答案相同,仅当myString
System.out.println(“testMyString”);
doAnswer(answer).when(mockFoo).addDate(eq(“myString”),any(Date.class));
mockFoo.addDate(“addme”,newdate());
mockFoo.addDate(“myString”,new Date());
//testMyString
//addDate(..)不应该被调用,而不是被模拟?
//addString(“myString”)
}
}
在编写上述用法的测试用例时,如何使用When/then在调用addDate时调用addString,但使用相同的参数
我不确定上面所说的是什么意思,所以我决定用一个工作示例来介绍我遇到的情况,注释中是每个测试的系统输出:
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")
}
}
公共类测试{
@统治
public MockitoRule MockitoRule=MockitoJUnit.rule();
//您的类的一个稍加修改的版本
公开课Foo{
public Foo addDate(字符串str,日期d){
System.out.println(“不应该调用addDate(..),而不是mock?”);
返回此;//需要返回一个Foo:)
}
公共Foo addString(String str){
System.out.println(“addString(\“”+str+“\”);
归还这个;
}
}
//要调用真正的方法,您需要间谍,这样您只能模拟
//需要不同功能的方法
@间谍
私人Foo mockFoo;
//在方法调用中使用param的答案
私人应答=调用->
mockFoo.addString(invocation.getArgument(0));
//回答使用固定参数的调用,而不是使用调用
私有应答staticAnswer=调用->
mockFoo.addString(“myString”);
@试验
公共无效测试答案(){
System.out.println(“testAnswer”);
doAnswer(answer).when(mockFoo).addDate(any(String.class),any(Date.class));
mockFoo.addDate(“addme”,newdate());
//测试者
//addString(“添加我”)
}
@试验
公共void testStaticAnswer(){
System.out.println(“testStaticAnswer”);
doAnswer(staticAnswer).when(mockFoo).addDate(any(String.class),any(Date.class));
mockFoo.addDate(“addme”,newdate());
//测试静态答案
//addString(“myString”)
}
@试验
public void testMyString(){//与Ruben的答案相同,仅当myString
System.out.println(“testMyString”);
doAnswer(answer).when(mockFoo).addDate(eq(“myString”),any(Date.class));
mockFoo.addDate(“addme”,newdate());
mockFoo.addDate(“myString”,new Date());
//testMyString
//addDate(..)不应该被调用,而不是被模拟?
//addString(“myString”)
}
}
完美。谢谢只要一个额外的问题。当我使用any()
时,它会抛出一个异常,因为在内部,它有一个notNull
检查。如何将非空值作为any()
传递可能是另一个问题,我在这里添加了这个问题:对。您还必须对文本字符串使用匹配器。使用eq
(参见我编辑的回答)完美。谢谢只要一个额外的问题。当我使用any()
时,它会抛出一个异常,因为在内部,它有一个notNull
检查。我怎么通过