J'ai essayé d'organiser la bonne utilisation de Mockito et PowerMock lors de la simulation de diverses méthodes lors des tests avec JUnit avec Spring Boot.
build.gradle
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile group: 'org.powermock', name: 'powermock-api-mockito', version: '1.6.6'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.6.6'
}
Insérez simplement spring-boot-starter-test et vous pourrez utiliser les deux bibliothèques suivantes. La version est ** spring-boot-gradle-plugin: 1.5.2.RELEASE **.
Ajoutez un paramètre pour utiliser la simulation de puissance qui sera utilisée plus tard.
TestTargetClass.java
@Component
public class TestTargetClass {
@Autowired
private TestSubClass testSubClass;
private String private_method() {
return "private_method called " + private_sub();
}
private String private_sub() {
return "private_sub";
}
public String public_method() {
return "public_method called " + public_sub();
}
public String public_sub() {
return "public_sub";
}
public String public_method_call_private_method() {
return "public_method called " + private_sub();
}
public static String static_method() {
return "static_method";
}
public String public_subclass_public_method() {
return "public_subclass_method called " + testSubClass.sub_public_method();
}
public String public_subclass_private_method() {
return "public_subclass_method called " + testSubClass.sub_public_method_call_private_method();
}
}
TestSubClass.java
@Component
public class TestSubClass {
public String public_field = "public_field";
private String private_field = "private_field";
private String sub_private_method() {
return "subclass_private_method has " + private_field;
}
public String sub_public_method() {
return "subclass_public_method has " + public_field;
}
public String sub_public_method_call_private_method() {
return "subclass_public_method called " + sub_private_method();
}
}
Vous pouvez utiliser Mockito pour la classe de test comme ceci.
RealTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class RealTest {
@Autowired
private TestTargetClass instance;
@Test
méthode de test public void() {
.....
}
}
Inutile d'écrire, voici le code de test
@Test
public void peut être testé en appelant des méthodes publiques() {
assertThat(public_method(), is("public_method called public_sub"));
}
OK si vous utilisez setAccessible avec réflexion
@Test
public void Peut être testé en appelant des méthodes privées() throws Exception {
Method method = TestTargetClass.class.getDeclaredMethod("private_method");
method.setAccessible(true);
assertThat((String) method.invoke(instance), is("private_method called private_sub"));
}
Inutile d'écrire, voici le code de test
@Test
public void Peut être testé en appelant des méthodes statiques() {
assertThat(TestTargetClass.static_method(), is("static_method"));
}
Voici le test utilisant la maquette du sujet principal.
Dans de tels cas, utilisez «Mockito.mock ()».
@Test
public void Vous pouvez vous moquer des méthodes publiques() {
TestTargetClass mockInstance = mock(TestTargetClass.class);
when(mockInstance.public_method()).thenReturn("mocked_public_method");
assertThat(mockInstance.public_method(), is("mocked_public_method"));
}
Je veux que les méthodes autres que la méthode moqueuse public_sub ()
fonctionnent comme implémentées, alors utilisez Mockito.spy ()
dans de tels cas.
@Test
public void La méthode Sub appelée par la méthode publique peut être simulée avec Spy() {
TestTargetClass mockInstance = spy(new TestTargetClass());
when(mockInstance.public_sub()).thenReturn("mocked_public_sub");
assertThat(mockInstance.public_method(), is("public_method called mocked_public_sub"));
}
La classe de test lors de l'utilisation de PowerMock ressemble à ceci
@RunWith(PowerMockRunner.class)
@PrepareForTest({TestTargetClass.class})
public class PowerMockTest {
@Test
méthode de test public void() {
.....
}
}
Utilisez PowerMockito.mock ()
et PowerMockito.when ()
. Aussi, utilisez MemberMatcher.method ()
pour refléter pour spécifier une méthode privée.
@Test
Les méthodes publiques void privées peuvent être simulées avec PowerMockito() throws Exception {
TestTargetClass mockInstance = PowerMockito.mock(TestTargetClass.class);
PowerMockito.when(mockInstance, MemberMatcher.method(TestTargetClass.class, "private_method"))
.withNoArguments().thenReturn("mocked_private_method");
//Utilisez la réflexion pour accéder aux méthodes privées
Method method = TestTargetClass.class.getDeclaredMethod("private_method");
method.setAccessible(true);
assertThat((String) method.invoke(mockInstance), is("mocked_private_method"));
}
Utilisez PowerMockito.mockStatic ()
et PowerMockito.when ()
.
@Test
Les méthodes statiques de public void peuvent être simulées avec PowerMockito()() {
PowerMockito.mockStatic(TestTargetClass.class);
PowerMockito.when(TestTargetClass.static_method()).thenReturn("mocked_static_method");
assertThat(TestTargetClass.static_method(), is("mocked_static_method"));
}
Je veux que les méthodes autres que la méthode moqueuse private_sub ()
fonctionnent comme implémentées, utilisez donc PowerMockito.spy ()
et PowerMockito.when ()
dans de tels cas. Cela reflète également l'utilisation de MemberMatcher.method ()
pour spécifier une méthode privée.
@Test
public void Les méthodes sous-privées appelées à partir de méthodes publiques peuvent être simulées avec spy() throws Exception {
TestTargetClass mockInstance = PowerMockito.spy(new TestTargetClass());
PowerMockito.when(mockInstance, MemberMatcher.method(TestTargetClass.class, "private_sub"))
.withNoArguments().thenReturn("mocked_private_sub");
assertThat(mockInstance.public_method_call_private_method(),
is("public_method called mocked_private_sub"));
}
On suppose que la classe de service qui est DI dans la classe de contrôleur est simulée.
PowerMock est également utilisé à ce moment.
DI la classe cible de @ Autowired
spécifiée dans la classe spécifiée par @ InjectMocks
dans l'annotation @ SpringBootTest
.
La classe cible de @ Autowired
est` PowerMockito.spy () ʻen tant que variable de classe.
La classe de test ressemble à ceci
@RunWith(PowerMockRunner.class)
//Classe cible PowerMock
@PrepareForTest({TestSubClass.class})
@SpringBootTest
public class PowerMockSubclassTest {
@InjectMocks
private TestTargetClass instance;
private TestSubClass testSubClass = PowerMockito.spy(new TestSubClass());
@Test
méthode de test public void() {
.....
}
}
Il semble que vous ne pouvez pas vous moquer même si vous faites ce qui suit au lieu de la variable de classe. ... peut-être Veuillez commenter s'il existe un bon moyen.
@Test
méthode de test public void() {
TestSubClass testSubClass = PowerMockito.spy(new TestSubClass());
}
Puisqu'il s'agit en fait d'une méthode publique, la partie où la sous-classe est déclarée dans la classe de test est
private TestSubClass testSubClass = PowerMockito.mock(TestSubClass.class);
C'est bon, mais il ne peut pas être utilisé avec celui utilisant spy () dans le même fichier source, donc je vais l'unifier avec spy ().
Utilisez PowerMockito.when ()
.
@Test
public void Peut se moquer des méthodes publiques des sous-classes() {
PowerMockito.when(testSubClass.sub_public_method()).thenReturn("mocked_subclass_public_method");
assertThat(instance.public_subclass_public_method(),
is("public_subclass_method called mocked_subclass_public_method"));
}
Utilisez PowerMockito.when ()
. Cela reflète également l'utilisation de MemberMatcher.method ()
pour spécifier une méthode privée.
@Test
public void Peut se moquer des méthodes privées des sous-classes() throws Exception {
PowerMockito.when(testSubClass, MemberMatcher.method(TestSubClass.class, "sub_private_method"))
.withNoArguments().thenReturn("mocked_sub_private_method");
assertThat(instance.public_subclass_private_method(), is(
"public_subclass_method called subclass_public_method called mocked_sub_private_method"));
}
Utilisez Whitebox.setInternalState ()
pour définir une simulation sur un champ de sous-classe.
@Test
public void Peut se moquer des champs publics des sous-classes() {
Whitebox.setInternalState(testSubClass, "public_field", "mocked_public_field");
assertThat(instance.public_subclass_public_method(),
is("public_subclass_method called subclass_public_method has mocked_public_field"));
}
Utilisez Whitebox.setInternalState ()
pour définir une simulation sur un champ de sous-classe.
Identique au réglage dans le domaine public.
@Test
public void Peut se moquer des champs privés des sous-classes() {
Whitebox.setInternalState(testSubClass, "private_field", "mocked_private_field");
assertThat(instance.public_subclass_private_method(), is(
"public_subclass_method called subclass_public_method called subclass_private_method has mocked_private_field"));
}
C'est une longue phrase, mais c'est tout.
Recommended Posts