[英]JMockit - Can't bind mocked class to tested class
I have an application with 3 layers: App <--> Graph <--> Couchbase 我有一个包含三层的应用程序:App <->图形<-> Couchbase
I'm trying to test the GraphConnector by mocking the couchbase layer and "replacing" it with a very basic in-memory graph implementation, using the same approach demonstrated in the JMockit tutorial . 我正在尝试通过模拟Couchbase层并使用非常基本的内存中图实现“替换”它来测试GraphConnector,使用JMockit 教程中演示的相同方法。
This is my test class (pardon the poor indentation, didn't get the hang of it yet): 这是我的测试课(请原谅可怜的缩进,还没有掌握):
public class GraphConnectorTest {
public static final class MockCouchbase extends MockUp<ICouchConnector> {
private Map<String, CouchEntry> couch;
@Mock
public void $clinit() {
couch = new HashMap<String, CouchEntry>();
}
@Mock
public void put(CouchEntry entry) {
couch.put(entry.getKey(), entry);
}
@Mock
public CouchEntry get(String key) {
return couch.get(key);
}
}
GraphConnectorImpl graph = new GraphConnectorImpl();
@BeforeClass
public static void setUpClass() {
new MockCouchbase();
}
@Test
public void testPost() throws Exception {
GraphNode node = new GraphNode(GraphNodeType.DOMAIN, "alon.com");
graph.post(node);
GraphNode retNode = graph.getSingleNode(node.getValue(), node.getType());
assertEquals(node.getValue(), retNode.getValue());
assertEquals(node.getType(), retNode.getType());
}
}
And here is my class under test: 这是我的课程正在测试:
public class GraphConnectorImpl implements IGraphConnector {
private static ICouchConnector couch = new CouchConnectorImpl(); // <-- Basic implementation which I don't want the test to execute
@Override
public void post(GraphNode node) {
CouchEntry entry = new CouchEntry(node.getValue(), JsonDocument.create(node.getValue()));
couch.put(entry);
}
@Override
public GraphNode getSingleNode(String nodeName, GraphNodeType nodeType) {
return new GraphNode(nodeType, couch.get(nodeName).getKey());
}
}
For some reason, the class MockCouchbase
that I created within the test class isn't automatically bound to the private field ICouchConnector couch
of the tested class, as shown in the tutorial. 由于某种原因,我在测试类中创建的类MockCouchbase
不会自动绑定到测试类的专用字段ICouchConnector couch
,如本教程所示。 Instead, the real implementation is called, which is obviously undesirable. 而是调用了真正的实现,这显然是不可取的。
If I remove the reference to the real implementation, I just get a good ol' NullPointerException
. 如果删除对实际实现的引用,我将得到一个很好的NullPointerException
。
I tried playing with the @Tested
and @Injectable
annotations but to no avail. 我尝试使用@Tested
和@Injectable
批注,但无济于事。
Solving my own question. 解决我自己的问题。
The problem with the way I wrote the class under test was explicitly invoking the constructor of the real implementation. 我编写被测类的方式的问题是显式调用实际实现的构造函数。 I'll be surprised if any mocking framework can "bypass" that. 如果任何模拟框架都可以“绕过”它,我会感到惊讶。
Instead, I should've created a constructor that gets ICouchConnector
as one of its arguments, eg use dependency injection properly. 相反,我应该创建一个构造函数,将ICouchConnector
作为其参数之一,例如,正确使用依赖项注入。
public class GraphConnectorImpl implements IGraphConnector {
private static ICouchConnector couch;
public GraphConnectorImpl(ICouchConnector connector) {
couch = connector;
}
// Rest of class...
}
JMockit will then attempt to find a constructor that corresponds to the fields annotated @Tested
and @Injectable
in the test class. 然后,JMockit将尝试查找与测试类中带注释的@Tested
和@Injectable
字段相对应的构造函数。
public class GraphConnectorTest {
@Tested
GraphConnectorImpl graph;
@Injectable
ICouchConnector couch;
// Rest of class...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.