JMockit - Невозможно привязать высмеянный класс к тестируемому классу
У меня есть приложение с 3 слоями: App <-> Graph <-> Couchbase
Я пытаюсь протестировать GraphConnector, высмеивая слой couchbase и "заменяя" его очень простой реализацией графа в памяти, используя тот же подход, который продемонстрирован в руководстве по JMockit.
Это мой тестовый класс (извините за плохой отступ, пока не освоил его):
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());
}
}
И вот мой тестируемый класс:
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());
}
}
По какой-то причине класс MockCouchbase
созданный в тестовом классе, автоматически не привязывается к закрытому полю ICouchConnector couch
протестированного класса, как показано в руководстве. Вместо этого вызывается реальная реализация, что, очевидно, нежелательно.
Если я удалю ссылку на реальную реализацию, я просто получу хороший NullPointerException
,
Я пытался играть с @Tested
а также @Injectable
аннотации, но безрезультатно.
1 ответ
Решаю свой вопрос.
Проблема с тем, как я написал тестируемый класс, заключалась в явном вызове конструктора реальной реализации. Я буду удивлен, может ли какая-то насмешливая структура "обойти" это.
Вместо этого я должен был создать конструктор, который получает ICouchConnector
в качестве одного из аргументов, например, правильно использовать внедрение зависимостей.
public class GraphConnectorImpl implements IGraphConnector {
private static ICouchConnector couch;
public GraphConnectorImpl(ICouchConnector connector) {
couch = connector;
}
// Rest of class...
}
Затем JMockit попытается найти конструктор, соответствующий аннотированным полям @Tested
а также @Injectable
в тестовом классе.
public class GraphConnectorTest {
@Tested
GraphConnectorImpl graph;
@Injectable
ICouchConnector couch;
// Rest of class...
}