看看这个奇怪的问题:
res1
null
为什么这不可能?
assertEquals
之间明确地更改它,并且此代码在单个JUnit线程中运行。res1
的其他字段或变量。什么可能?我假设它不是JVM中的错误,但谁知道。
正如Jon Skeet所说,问题在于实例不同。这是由这个奇怪的反思问题造成的:
public class ServiceObject {
private static final Map<Class<?>, Map<String, Operation>> opsByClass =
new ConcurrentHashMap<Class<?>, Map<String,Operation>>();
private final Object target;
private final Map<String, Operation> myClassOps;
private class Operation {
private final Method method;
public Operation(Method met) {
this.method = met;
method.setAccessible(true);
}
public void execute(Map<String,?> args, Responder responder, Object context, boolean coerce) {
...
method.invoke(target, mArgs);
}
}
public ServiceObject(Object target) {
Class<?> myClass = target.getClass();
Map<String, Operation> op = opsByClass.get(myClass);
if (op == null) {
op = new HashMap<String, Operation>();
for (Method meth : myClass.getMethods()) {
...
op.put(opName, new Operation(meth));
}
opsByClass.put(myClass, op);
}
this.target = target;
this.myClassOps = op;
}
public void execute(String opName) {
Operation op = myClassOps.get(opName);
...
op.execute(args, responder, context, coerce);
}
}
// Foo is equivalent to the class that contains <res1> above
class Foo {
@ServiceOperation
public void bar() {
// breakpoint here
}
}
运行测试时会发生什么:
a = new Foo();
b = new Foo();
svc = new ServiceObject(a);
svc.execute("bar", ...); // inside Foo.bar() <this> will be <a>
svc = new ServiceObject(b);
svc.execute("bar", ...); // inside Foo.bar() <this> will still be <a>, but should be <b>
答案 0 :(得分:4)
猜测:在断言阶段,你正在查看类的不同实例,而不是设置为“bar”时的类。
虽然没有看到其余的代码,但很难说。
编辑:问题是您的opsByClass
缓存将包含一个操作,该操作隐式具有关联的ServiceObject
。因此,当您使用ServiceObject
创建第一个Foo
时,它将缓存与第一个ServiceObject
实例关联的操作实例。当您在svc.execute
的第二个实例上调用ServiceObject
时,它将在地图中查找操作,并找到与第一个实例关联的Operation
。 ..这可能不是你想要的。
答案 1 :(得分:0)
我猜你的代码跨越了不同的测试。
建议你在onSetUp()方法中进行设置
答案 2 :(得分:0)
我找到了。问题在于,因为Operation
不是static
,所以它指的是最初创建的ServiceObject
,而不是执行第二次调用的{{1}}。