Ich habe versucht, die ordnungsgemäße Verwendung von Mockito und PowerMock zu organisieren, wenn ich beim Testen mit JUnit mit Spring Boot verschiedene Methoden verspottete.
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'
}
Fügen Sie einfach den Spring-Boot-Starter-Test ein und Sie können die folgenden zwei Bibliotheken verwenden. Die Version ist ** Spring-Boot-Gradle-Plugin: 1.5.2.RELEASE **.
Fügen Sie eine Einstellung hinzu, um das Power Mock zu verwenden, das später verwendet wird.
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();
}
}
Sie können Mockito für diese Testklasse verwenden.
RealTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class RealTest {
@Autowired
private TestTargetClass instance;
@Test
öffentliche Leertestmethode() {
.....
}
}
Unnötig zu schreiben, hier ist der Testcode
@Test
public void kann durch Aufrufen öffentlicher Methoden getestet werden() {
assertThat(public_method(), is("public_method called public_sub"));
}
OK, wenn Sie setAccessible mit Reflektion verwenden
@Test
public void Kann durch Aufrufen privater Methoden getestet werden() throws Exception {
Method method = TestTargetClass.class.getDeclaredMethod("private_method");
method.setAccessible(true);
assertThat((String) method.invoke(instance), is("private_method called private_sub"));
}
Unnötig zu schreiben, hier ist der Testcode
@Test
public void Kann durch Aufrufen statischer Methoden getestet werden() {
assertThat(TestTargetClass.static_method(), is("static_method"));
}
Hier ist der Test mit dem Mock des Hauptthemas.
Verwenden Sie in solchen Fällen Mockito.mock ()
.
@Test
public void Sie können öffentliche Methoden verspotten() {
TestTargetClass mockInstance = mock(TestTargetClass.class);
when(mockInstance.public_method()).thenReturn("mocked_public_method");
assertThat(mockInstance.public_method(), is("mocked_public_method"));
}
Ich möchte, dass die anderen Methoden als die Verspottungsmethode "public_sub ()" wie implementiert funktionieren. Verwenden Sie daher in solchen Fällen "Mockito.spy ()".
@Test
public void Die von der public-Methode aufgerufene Sub-Methode kann mit Spy verspottet werden() {
TestTargetClass mockInstance = spy(new TestTargetClass());
when(mockInstance.public_sub()).thenReturn("mocked_public_sub");
assertThat(mockInstance.public_method(), is("public_method called mocked_public_sub"));
}
Die Testklasse bei Verwendung von PowerMock sieht folgendermaßen aus
@RunWith(PowerMockRunner.class)
@PrepareForTest({TestTargetClass.class})
public class PowerMockTest {
@Test
öffentliche Leertestmethode() {
.....
}
}
Verwenden Sie "PowerMockito.mock ()" und "PowerMockito.when ()". Verwenden Sie außerdem "MemberMatcher.method ()", um eine private Methode anzugeben.
@Test
public void private Methoden können mit PowerMockito verspottet werden() throws Exception {
TestTargetClass mockInstance = PowerMockito.mock(TestTargetClass.class);
PowerMockito.when(mockInstance, MemberMatcher.method(TestTargetClass.class, "private_method"))
.withNoArguments().thenReturn("mocked_private_method");
//Verwenden Sie Reflection, um auf private Methoden zuzugreifen
Method method = TestTargetClass.class.getDeclaredMethod("private_method");
method.setAccessible(true);
assertThat((String) method.invoke(mockInstance), is("mocked_private_method"));
}
Verwenden Sie "PowerMockito.mockStatic ()" und "PowerMockito.when ()".
@Test
Statische Methoden für öffentliche Leeren können mit PowerMockito verspottet werden()() {
PowerMockito.mockStatic(TestTargetClass.class);
PowerMockito.when(TestTargetClass.static_method()).thenReturn("mocked_static_method");
assertThat(TestTargetClass.static_method(), is("mocked_static_method"));
}
Ich möchte, dass die anderen Methoden als die Verspottungsmethode "private_sub ()" wie implementiert funktionieren. Verwenden Sie daher in solchen Fällen "PowerMockito.spy ()" und "PowerMockito.when ()". Verwenden Sie außerdem "MemberMatcher.method ()", um eine private Methode anzugeben.
@Test
public void Subprivate Methoden, die von öffentlichen Methoden aufgerufen werden, können mit Spion verspottet werden() 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"));
}
Es wird angenommen, dass die Serviceklasse DI in der Controller-Klasse verspottet ist. Zu diesem Zeitpunkt wird auch PowerMock verwendet. DI die Zielklasse von "@ Autowired", die in der durch "@ InjectMocks" in der Annotation "@ SpringBootTest" angegebenen Klasse angegeben ist. Die Zielklasse von "@ Autowired" ist "PowerMockito.spy ()" als Klassenvariable.
Die Testklasse sieht so aus
@RunWith(PowerMockRunner.class)
//PowerMock-Zielklasse
@PrepareForTest({TestSubClass.class})
@SpringBootTest
public class PowerMockSubclassTest {
@InjectMocks
private TestTargetClass instance;
private TestSubClass testSubClass = PowerMockito.spy(new TestSubClass());
@Test
öffentliche Leertestmethode() {
.....
}
}
Es scheint, dass Sie nicht verspotten können, selbst wenn Sie anstelle der Klassenvariablen Folgendes tun. ... Vielleicht Bitte kommentieren Sie, ob es einen guten Weg gibt.
@Test
öffentliche Leertestmethode() {
TestSubClass testSubClass = PowerMockito.spy(new TestSubClass());
}
Da es sich tatsächlich um eine öffentliche Methode handelt, ist der Teil, in dem die Unterklasse in der Testklasse deklariert ist, der
private TestSubClass testSubClass = PowerMockito.mock(TestSubClass.class);
Es ist in Ordnung, aber es kann nicht zusammen mit dem verwendet werden, der spy () in derselben Quelldatei verwendet, also werde ich es mit spy () vereinheitlichen.
Verwenden Sie PowerMockito.when ()
.
@Test
public void Kann öffentliche Methoden von Unterklassen verspotten() {
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"));
}
Verwenden Sie PowerMockito.when ()
. Verwenden Sie außerdem "MemberMatcher.method ()", um eine private Methode anzugeben.
@Test
public void Kann private Methoden von Unterklassen verspotten() 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"));
}
Verwenden Sie "Whitebox.setInternalState ()", um ein Modell für ein Unterklassenfeld festzulegen.
@Test
public void Kann öffentliche Felder von Unterklassen verspotten() {
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"));
}
Verwenden Sie "Whitebox.setInternalState ()", um ein Modell für ein Unterklassenfeld festzulegen. Entspricht der Einstellung im öffentlichen Bereich.
@Test
public void Kann private Felder von Unterklassen verspotten() {
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"));
}
Es ist ein langer Satz, aber das war's.
Recommended Posts