web-dev-qa-db-fra.com

Utilisation de PowerMockito.whenNew () ne se moque pas et méthode originale est appelée

J'ai un code un peu comme ceci ci-dessous:

Class A {
  public boolean myMethod(someargs) {
    MyQueryClass query = new MyQueryClass();
    Long id = query.getNextId();
    // some more code
  }
}
Class MyQueryClass     {
  ....
  public Long getNextId() {
    //lot of DB code, execute some DB query
    return id;
  }
}

Maintenant, je suis en train d'écrire un test pour A.myMethod(someargs). Je souhaite ignorer la méthode réelle query.getNextId() et renvoyer à la place une valeur de stub. En gros, je veux me moquer de MyQueryClass.

Donc, dans mon cas de test, j'ai utilisé:

MyQueryClass query = PowerMockito.mock(MyQueryClass.class);
PowerMockito.whenNew(MyQueryClass.class).withNoArguments().thenReturn(query);
when(query.getNextId()).thenReturn(1000000L);

boolean b = A.getInstance().myMethod(args);

//asserts

J'ai utilisé @RunWith(PowerMockRunner.class) et @PrepareForTest({MyQueryClass.class}) au début de ma classe de test.

Mais lorsque je débogue le test, il appelle toujours la méthode réelle getNextId() de la classe MyQueryClass.

Qu'est-ce que j'oublie ici? Est-ce que n'importe qui peut aider comme je suis nouveau à Mockito et à PowerMockito.

64
user3942446

Vous devez mettre la classe où le constructeur est appelé dans l'annotation @PrepareForTest au lieu de la classe en cours de construction - voir Construction fictive de nouveaux objets .

Dans ton cas:

@PrepareForTest(MyQueryClass.class)

@PrepareForTest(A.class)

Plus général:

@PrepareForTest(NewInstanceClass.class)

@PrepareForTest(ClassThatCreatesTheNewInstance.class)

144
TrueDub

Comme @TrueDub mentionné dans sa réponse acceptée, vous devez ajouter la classe où le constructeur est appelé au @PrepareForTest

Cependant, si vous faites cela, la couverture pour cette classe, telle que rapportée par eclemma et Sonar, sera nulle pour cette classe.

wiki Powermockito

Nous allons remplacer Javassist par ByteBuddy (# 727) et il devrait aider à résoudre ce vieux problème. Mais pour le moment, il n’ya AUCUN MOYEN D’UTILISER PowerMock avec JaCoCo Une instrumentation à la volée. Et aucune solution de contournement à obtenir une couverture de code dans l'IDE.

La solution ici serait donc de refactoriser le code afin d’utiliser une fabrique statique qui renverrait une instance de cette classe puis la simulait de manière statique.

1
ACV