我目前正在在ActionEvent内部使用大量's的代码库上编写单元测试,并且由于ActionEvent没有覆盖equals(),我正在创建一个自定义ArgumentMatcher来匹配ActionEvent's。
我ArgumentMatcher目前看起来像这样:
public class ActionEventMatcher extends ArgumentMatcher<ActionEvent> {
private Object source;
private int id;
private String actionCommand;
public ActionEventMatcher(Object source, int id, String actionCommand) {
this.source = source;
this.id = id;
this.actionCommand = actionCommand;
}
@Override
public boolean matches(Object argument) {
if (!(argument instanceof ActionEvent))
return false;
ActionEvent e = (ActionEvent)argument;
return source.equals(e.getSource()) &&
id == e.getId() && actionCommand.equals(e.getActionCommand());
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以更改我的ArgumentMatcher以便它接受从其他匹配器创建的参数。例如,如果我调用了actionEvent()一个返回匹配器的方法,我希望能够执行以下操作:
verify(mock).fireEvent(argThat(actionEvent(same(source), anyInt(), …Run Code Online (Sandbox Code Playgroud) 我创建了一个ArgumentMatcher,
private class IsListOf2Elements implements ArgumentMatcher<List<String>>{
@Override
public boolean matches(List<String> argument) {
return ((List<String>)argument).size()==2;
}
}
Run Code Online (Sandbox Code Playgroud)
我想否定这个匹配,所以当大小不是 2 时匹配,
Mockito.doReturn(false).when(mock).addAll(Mockito.argThat(AdditionalMatchers.not(new IsListOf2Elements())));
Run Code Online (Sandbox Code Playgroud)
但这是不正确的。我明白了,
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
No matchers found for additional matcher Not(?)
-> at my.test.own.Mockito_aTest.test4e(Mockito_aTest.java:136)
Run Code Online (Sandbox Code Playgroud) 我基本上是在尝试验证是否在方法中调用了正确的参数。
这是我尝试测试的代码片段:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.in("type", Arrays.asList("employee", "supervisor");
Run Code Online (Sandbox Code Playgroud)
使用以下方法验证:
Mockito.verify(mockSession).createCriteria(User.class);
Mockito.verify(mockCriteria).add(Restrictions.in("type", Arrays.asList("employee", "supervisor"));
Run Code Online (Sandbox Code Playgroud)
第一个验证语句有效。第二个不是,因为我相信 JVM 检测到两个不同的List对象进行比较。但是,当我将第二个验证语句更改为:
Mockito.verify(mockCriteria).add(Restrictions.in("type", Mockito.anyList());
Run Code Online (Sandbox Code Playgroud)
它就像一个魅力。但是,我确实想确保员工和主管这两个字符串在内部,List并且使用Mockito.anyList().
我如何让这个工作?
编辑:请注意,我不想只验证列表是否已通过。我想确保在该列表中传递正确的字符串
我在使用 Mockito 框架的测试中有以下代码来验证是否drawTextOnCanvas()使用正确的参数调用了该方法。
// The two objects below are mocks. The rest of the objects used in
// the call to verify() are plain old java objects I've instantiated elsewhere.
BufferedImage testImage = Mockito.mock(BufferedImage.class);
Mockito.when(testImage.getHeight()).thenReturn(10);
Graphics mockGraphics = Mockito.mock(Graphics.class);
Mockito.when(mockGraphics.getFontMetrics(Matchers.any(Font.class)))
.thenReturn(Mockito.mock(FontMetrics.class));
Mockito.verify(drawingUtil).drawTextOnCanvas(
Matchers.eq(imageCategory.getWidth()),
Matchers.eq(mockGraphics),
Matchers.any(Font.class),
Matchers.eq(Arrays.asList("Test text")),
Matchers.eq(testImage.getHeight() + 10),
Matchers.any(FontMetrics.class),
Matchers.eq(10));
Run Code Online (Sandbox Code Playgroud)
但是它抛出以下异常:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 4 recorded:
-> at com.test.package(ExampleTest.java:66)
-> at com.test.package(ExampleTest.java:67)
-> at com.test.package(ExampleTest.java:67)
-> at com.test.package(ExampleTest.java:68)
This exception …Run Code Online (Sandbox Code Playgroud) 我最近看到一些像这样工作的Mockito 1.9.5代码:
MyObject myObject = new MyObject();
...
Mockito.when(myObject.someMethod()).thenReturn("bogus");
Run Code Online (Sandbox Code Playgroud)
由于myObject 不是一个模拟对象,而是一个非模拟类的实例,我很惊讶这个编译并运行而不会失败单元测试.我预计我会失败说"你让我对非模拟对象设置期望,我希望只对模拟对象设置期望."
为什么这段代码不会导致测试失败?
更新:添加更多代码来实际复制我发现令人困惑的行为.这些例子充分说明了我的问题.以下代码的行为与我预期的一样 - 当我运行此测试时,测试失败并显示一条消息
when()需要一个必须是'对mock进行方法调用'的参数.
public class AnotherObject{
public String doSomething(){
return "did something";
};
}
public class MyObject{
private AnotherObject anotherObject = new AnotherObject();
public void setAnotherObject(AnotherObject anotherObject) {
this.anotherObject = anotherObject;
}
public String someMethod(){
return anotherObject.doSomething();
}
}
@Test
public void WhyDoesWhenWorkOnNonMock() throws Exception {
MyObject myObject = new MyObject();
Mockito.when(myObject.someMethod()).thenReturn("bogus");
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我为这个人为的测试添加一些特定的行,那么即使我期望与以前相同的失败和相同的消息,测试也不会失败:
public class AnotherObject{
public String …Run Code Online (Sandbox Code Playgroud) 我不知道Mockito.verify在这种情况下我该怎么用.如何将false传递给Mockito.verify?我尝试了两种不同的方法,但它不起作用.
public Sample someMethod(Sample s, boolean a){....}
@Test
public void test() {
...
verify(mock).someMethod(sampleCaptor.capture(), false));
verify(mock).someMethod(sampleCaptor.capture(), org.mockito.Matchers.eq(false)));
...
}
Run Code Online (Sandbox Code Playgroud) 我试图像这样使用Mockito:
Mockito.when(Mockito.any(ObjectMapper.class).readValue(Mockito.any(BufferedReader.class),Mockito.any(Class.class))).thenReturn(new Person("1","abc"));
Run Code Online (Sandbox Code Playgroud)
这是来自杰克逊图书馆.
public <T> T readValue(Reader src, Class<T> valueType)
Run Code Online (Sandbox Code Playgroud)
我这样做的原因是因为我到达代码的这一点时,有大量的对象被创建.嘲笑每一步都需要时间.
当代码到达这个mockito语句时,我得到NPE的原因是什么?
堆栈跟踪 :
java.lang.NullPointerException
at com.prashant.flax.ShellTest.givenDirectoryHasFiles(ShellTest.java:139)
at com.prashant.flax.ShellTest.testExecute(ShellTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,它是在给定的方法中(这个方法只有这段代码),所以我可以看到调试时,它到达那里并崩溃.
我正在尝试when使用多个any参数定义mockito 方法:
TestBedDaoClient testBedDaoClient = mock(TestBedDaoClient.class);
when(testBedDaoClient.addTestBed(anyString(), anyString(), any(VCloudConfiguration.class))).thenReturn(testBedPojoMockData);
Run Code Online (Sandbox Code Playgroud)
在目标测试类中:
TestBedPojo addedTestBedPojo = testBedDaoClient.addTestBed(testBedName, testBedDescription, vCloudConfiguration);
Run Code Online (Sandbox Code Playgroud)
在 DAO 客户端中:
public TestBedPojo addTestBed(String testBedName, String testBedDescription, VCloudConfiguration vCloudConfiguration){
return testBedPojo;
}
Run Code Online (Sandbox Code Playgroud)
我想以when这样一种方式定义它返回testBedPojoMockData任何参数值。但我收到错误:Argument(s) are different!
我什至试过:
when(testBedDaoClient.addTestBed("test", "test", any(VCloudConfiguration.class))).thenReturn(testBedPojoMockData);
when(testBedDaoClient.addTestBed(any(), any(), any())).thenReturn(testBedPojoMockData);
Run Code Online (Sandbox Code Playgroud)
但没有运气。我如何定义它when以便它在任何调用中返回模拟数据?
我有方法:
public void loadPlatformDependencies() {
try {
dependenciesRepository.deleteAll();
dependenciesRepository.saveAll(pullLastDependencies());
publisher.publishEvent(new LoadedDependenciesEvent());
} catch (Exception e) {
LOGGER.error("Failed to load dependencies", e);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试测试它:
@Test
public void testLoadPlatformDependencies() {
ArgumentCaptor<Iterable<Dependency>> captor = ArgumentCaptor.forClass(Iterable.class);
when(dependenciesRepository.saveAll(captor.capture())).thenReturn(any(Iterable.class));
puller.loadPlatformDependencies();
verify(dependenciesRepository,times(1)).deleteAll();
verify(dependenciesRepository, times(1)).saveAll(any(Iterable.class));
verify(publisher,times(1)).publishEvent(any());
}
Run Code Online (Sandbox Code Playgroud)
但有一个问题,该方法 pullLastDependency() 现在工作不正确。我有一个错误:
Invalid use of argument matchers!
0 matchers expectd, 1 recorded:
Run Code Online (Sandbox Code Playgroud)
方法 pullLastDependency() 返回列表。我可以在没有正常工作的方法 pullLastDependency() 的情况下测试此方法吗?或者也许我应该以另一种方式测试这个方法?
谁能解释一下在嘲讽中正在进行的存根及其如何帮助在Junit Testcase中编写和嘲笑方法。