我正在使用Mockito编写Junit测试,该测试接受相同的参数,但在其中一个参数中使用不同的子参数。例如:
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
public class SampleMockito {
@Mock
private Widget widget;
private static Machine machine;
@BeforeClass
public static void init() {
machine = new Machine();
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Mockito.when(widget.doAction(Mockito.eq("Setting 1"), Mockito.any(Values.class))).thenReturn("Action 1 done.");
Mockito.when(widget.doAction(Mockito.eq("Setting 1"), Mockito.any(Values.class))).thenReturn("Action 2 done.");
Mockito.when(widget.doAction(Mockito.eq("Setting 2"), Mockito.any(Values.class))).thenReturn("Action 3 done.");
Mockito.when(widget.doAction(Mockito.eq("Setting 2"), Mockito.any(Values.class))).thenReturn("Action 4 done.");
}
@Test
public void testPerformAction() {
// Some sample test code that I have not written.
}
}
这是我的POJO
public class Widget {
public String doAction(String param, Values values) {
System.out.println("Do Some Irrelevant Action");
return null;
}
}
和工人阶级
import java.util.ArrayList;
import org.jsoup.nodes.Document;
public class Machine {
public boolean performAction(Widget w, Document doc) {
// Action 1
w.doAction("Setting 1", new Values("Argument 1", "Argument 2"));
// Action 2
w.doAction("Setting 1", new Values("Argument 1a", new Exception("Exception message.")));
// Action 3
w.doAction("Setting 2", new Values("Argument 1", "Argument 2"));
// Action 4
w.doAction("Setting 2", new Values("Argument 1a", new Exception("Exception message.")));
return false;
}
}
class Values extends ArrayList<Object> {
public Values() {
}
public Values(Object... vals) {
super(vals.length);
for (Object o : vals) {
add(o);
}
}
}
正如他们目前所定义的那样,Mockito无法区分行动1和行动2以及行动3和行动4.我希望能够告诉Mockito它应该期待一定数量的字符串,或期望某种类型的异常作为Values对象的参数。在Mockito有办法做到这一点吗?还是其他一些模拟测试框架?
答案 0 :(得分:0)
根据@JB Nizet的建议,我改变了我的代码以实现 argThat(...),删除了Values和ArrayList之间的继承关系,并实现了{{3}使用 argThat():
package tinkering;
import java.util.List;
import org.jsoup.nodes.Document;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import tinkering.Machine.Values;
public class SampleMockito {
@Mock
private Widget widget;
private static Machine machine;
private List<Object> vals;
@BeforeClass
public static void init() {
machine = new Machine();
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@SuppressWarnings("unchecked")
@Test
public void testPerformAction() {
machine.performAction(widget, new Document("dumb"));
Mockito.verify(widget).doAction(Mockito.eq("Setting 1"), (Values) Mockito.argThat(new PerformActionArgumentStringArgsMatcher()));
Mockito.verify(widget).doAction(Mockito.eq("Setting 1"), (Values) Mockito.argThat(new PerformActionArgumentMixedArgsMatcher()));
Mockito.verify(widget).doAction(Mockito.eq("Setting 2"), (Values) Mockito.argThat(new PerformActionArgumentStringArgsMatcher()));
Mockito.verify(widget).doAction(Mockito.eq("Setting 2"), (Values) Mockito.argThat(new PerformActionArgumentMixedArgsMatcher()));
}
class PerformActionArgumentStringArgsMatcher extends ArgumentMatcher {
@Override
public boolean matches(Object arg) {
if (arg instanceof Values) {
vals = ((Values) arg).getList();
if (vals.size() != 2)
return false;
if (!vals.get(0).equals("Argument 1"))
return false;
if (!vals.get(1).equals("Argument 2"))
return false;
}
return true;
}
}
class PerformActionArgumentMixedArgsMatcher extends ArgumentMatcher {
@Override
public boolean matches(Object arg) {
if (arg instanceof Values) {
vals = ((Values) arg).getList();
if (vals.size() != 2)
return false;
if (!vals.get(0).equals("Argument 1a"))
return false;
if (!(vals.get(1) instanceof Exception) && !((Exception) vals.get(1)).getMessage().equals("Exception message."))
return false;
}
return true;
}
}
}
对Machine.java的更改:
package tinkering;
import java.util.ArrayList;
import org.jsoup.nodes.Document;
public class Machine {
public boolean performAction(Widget w, Document doc) {
// Action 1
w.doAction("Setting 1", new Values("Argument 1", "Argument 2"));
// Action 2
w.doAction("Setting 1", new Values("Argument 1a", new Exception("Exception message.")));
// Action 3
w.doAction("Setting 2", new Values("Argument 1", "Argument 2"));
// Action 4
w.doAction("Setting 2", new Values("Argument 1a", new Exception("Exception message.")));
return false;
}
class Values {
private ArrayList<Object> list;
public ArrayList<Object> getList() {
return list;
}
public void setList(ArrayList<Object> list) {
this.list = list;
}
public Values() {
}
public Values(Object... vals) {
list = new ArrayList<Object>();
for (Object o : vals) {
list.add(o);
}
}
}
编译并成功通过。