[07/10/06 4:00 Exemple de code édité] J'essaie de tester du code (en utilisant JMockIt avec TestNG) sans toucher à la base de données, mais il semble qu'une méthode mockée est encore en fait appelé. Voici la configuration simplifiée:JMockIt Mocked Méthode non moqueuse
class DBRow {
public DBRow() { }
public DBRow(Object obj) {
initialize(obj);
}
public void insert() {
actuallyAddRowToDatabase();
}
}
class MyObject extends DBRow {
MyObject(Object obj) {
super(obj);
}
public void insert(Object obj) {
doSomething(obj);
insert();
}
}
class Factory {
static MyObject createObject(Object obj1, Object obj2) {
MyObject newObj = new MyObject(obj1);
newObj.insert(obj2);
return newObj;
}
}
Je voulais railler l'opération d'insertion pour empêcher une insertion dans la base de données réelle, alors j'ai essayé quelque chose comme ceci:
@Test
public void testCreation() {
new Expectations(MyObject.class) {
MyObject mock = new MyObject(null) {
@Mock
public void insert(Object obj) { }
};
{
new MyObject(anyString); result = mock;
}};
MyObject test = Factory.createObject("something", "something else");
}
Mais il semble que le vrai insert(Object)
est toujours appelé. Je précise que la classe est ridiculisée, donc toutes les instances devraient être moquées, n'est-ce pas? Et je spécifie que la méthode d'insertion doit être raillée, alors pourquoi la méthode réelle serait appelée?
Il y a aussi un deuxième problème avec ce qui précède. Lorsque je définis la classe mock dans le bloc Expectations (comme ci-dessus), il semble que seul le constructeur Row()
est appelé au lieu de Row(Object)
, et donc l'objet n'est pas correctement initialisé. J'ai corrigé ceci en le déplaçant dans une méthode @BeforeTest
et en instanciant la classe là. Voilà ce qui ressemble à:
private MyObject mock;
@BeforeTest
public void beforeTest() {
new MockUp<MyObject>() {
@Mock
public void insert(Object obj) { }
};
mock = new MyObject("something");
}
@Test
public void testCreation() {
new Expectations(MyObject.class) {{
new MyObject(anyString); result = mock;
}};
MyObject test = Factory.createObject("something", "something else");
}
Donc cela semble obtenir le constructeur correct d'être appelé, mais il semble encore que insert()
est appelé aussi bien. Des idées?
testStuff()
n'est pas en cause. En fait, je vais le retirer de mon exemple. Le problème est leinsert()
pendant la construction. Je vais modifier mon exemple pour le clarifier, je l'espère. Cependant, vous dites "Toutes les instances ne seront pas automatiquement mockées", mais dans la documentation il dit: "Si un objet Class est donné [dans le constructeur Expectations] ... toutes les instances de la classe spécifiée seront considérées comme des instances mockées ". Pouvez-vous clarifier votre déclaration? – DidjitPointez-moi vers la documentation que vous citez.Comprenez que 'Expectations' une phase d'enregistrement pour les invocations sur des instances mockées. Sa phase de création d'objet non mockée. Objets mockés créés en utilisant 'new MockUp' ou par' Mock' et Ìnjectable' –
Aussi, c'est très déroutant de lire votre code. Vous 'MyObject'définition a seulement un constructeur, 'MyObject (Object obj)' mais dans votre code de test, vous faites, 'new MyObject (" quelque chose "," quelque chose d'autre ");' donc je ne suis pas sûr de ce que je cherche à. Si vos méthodes réelles sont appelées, c'est le cas que vous appelez la méthode sur un objet réel et non un faux. –