我的测试方法中有以下带有 JMock 期望的代码段:
context.checking(new Expectations() {{
allowing(listener).tableChanged(with(anyInsertionEvent()));
oneOf(listener).tableChanged(with(aRowChangedEvent(0)));
}});
哪里anyInsertionEvent
和 aRowChangedEventAs
返回 Matcher<TableModelEvent>
的实例.
这摘自书“Growing Object-Oriented Software Guided by Tests”(第 181 页)。
我尝试将此测试转换为 Groovy,但我需要的方法:
org.jmock.Expectations.with(org.hamcrest.Matcher<T>)
阴影:
org.codehaus.groovy.runtime.DefaultGroovyMethods.with(java.lang.Object,
groovy.lang.Closure<T>)
因此,我在测试期间遇到如下错误:
groovy.lang.MissingMethodException: No signature of method: $Proxy8.tableChanged() is applicable for argument types: (java.lang.Boolean) values: [false]
Possible solutions: tableChanged(javax.swing.event.TableModelEvent)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.rorick.auctionsniper.ui.SnipersTableModelTest$1.<init>(SnipersTableModelTest.groovy:43)
at org.rorick.auctionsniper.ui.SnipersTableModelTest.setSniperValuesInColumns(SnipersTableModelTest.groovy:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at org.jmock.integration.junit4.JMock$1.invoke(JMock.java:37)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:105)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:98)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:61)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:54)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:52)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
我怎样才能使用合适的with
方法?或者,请建议任何其他方法来解决此问题。
更新:它不是阴影。实际调用的方法是Expectations.with(Matcher<Boolean>)
因此 false
堆栈跟踪中的值。因此,方法被错误地调度。知道如何处理吗?
更新:匹配器方法如下:
public Matcher<TableModelEvent> anyInsertionEvent() {
Matcher<Integer> insertMatcher = equalTo(TableModelEvent.INSERT);
return new FeatureMatcher<TableModelEvent, Integer>(insertMatcher, "is an insertion event", "event type") {
@Override
protected Integer featureValueOf(TableModelEvent actual) {
return actual.getType();
}
};
}
private Matcher<TableModelEvent> aRowChangedEvent(int row) {
return samePropertyValuesAs(new TableModelEvent(model, row));
}
最佳答案
最后,我找到了一个解决方法。请参阅下面的检查代码。 new Expectations() {{}}
Java 语法已经消失,取而代之的是闭包:
context.checking {
allowing(listener).tableChanged(argThat(anyInsertionEvent()));
oneOf(listener).tableChanged(argThat(aRowChangedEvent(0)));
}
请注意 with
替换为 argThat
(模仿 Mockito)。 context
不是 org.jmock.integration.junit4.JUnit4Mockery
的实例可以说,它是以下类的一个实例:
class JUnit4GroovyMockery extends JUnit4Mockery {
public void checking(Closure c) {
ClosureExpectations expectations = new ClosureExpectations();
expectations.closureInit(c, expectations);
super.checking(expectations);
}
private static class ClosureExpectations extends Expectations {
void closureInit(Closure cl, Object delegate) {
cl.setDelegate(delegate);
cl.call();
}
public Object argThat(Matcher<?> matcher) {
currentBuilder().addParameterMatcher(matcher);
return null;
}
}
}
这是基于来自 http://docs.codehaus.org/display/GROOVY/Using+JMock+with+Groovy 的 JUnit4GroovyMockery 类. argThat
从 Expectations.with(Matcher<T>)
复制粘贴和 Expectations.addParameterMatcher(Matcher<?>)
.
这对我有用,尽管我对这个解决方案不是很满意;我更愿意保留 with
方法的名称。
关于groovy - 在 Groovy : problems with 'with' method 中将 JMock2 与匹配器一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12270789/