如何使用 Mockito 测试带有私有方法调用的 void 方法
How to test void method with private method calls using Mockito
我有如下一段代码
public class A extends B {
private boolean workDone = false;
@Override
public void publicMethod(boolean flag) {
if (!workDone) {
privateMethod();
workDone = true;
}
super.publicMethod(flag);
}
private void privateMethod() {
// some logic here
}
}
我是模拟新手。我有以下疑问。我正在尝试测试 public 方法。
- 我可以断言私有变量 workDone 的值吗?
- 是否可以验证super中的方法调用class?
- 如何模拟方法中的私有方法调用?
在进行单元测试时,我们会验证public被测代码的可观察行为。这是 CUT 传送的return 值 及其与依赖项 的 通信
CUT 中的私有变量和私有方法是 实现细节 我们不想(明确地)测试,因为我们希望它们可以在不中断测试的情况下改变。
在极少数情况下,对超级 class 方法的调用可以被视为 "communication with dependency"。在这种情况下,您创建了 CUT 的 spy()
。但通常这也应该被视为 实施细节 ...
- 没有。私有变量只能通过反射访问。这通常不是首选,尤其是在单元测试中。
- 是的,假设您对超级 class 方法调用进行了一些可断言的更改。喜欢
boolean flag
中的变化
- 是的,您可以使用 powermockito。有关更多信息,请参见此处。
Testing Private method using mockito
如果你真的想验证它,你需要改变你的A class 并将超级调用提取到私有方法中:
public class A extends B {
private boolean workDone = false;
@Override
public void publicMethod(final boolean flag) {
if (!workDone) {
privateMethod();
workDone = true;
}
callParentPublicMethod(flag);
}
private void callParentPublicMethod(final boolean flag) {
super.publicMethod(flag);
}
private void privateMethod() {
System.out.println("A: privateMethodCalled");
}
}
完成此操作后,您可以使用 PowerMock 来验证私有方法调用:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ A.class })
public class ATest {
@Test
public void publicMethod_test_false() throws Exception {
A spy = PowerMockito.spy(new A());
spy.publicMethod(false);
PowerMockito.verifyPrivate(spy).invoke("privateMethod");
PowerMockito.verifyPrivate(spy).invoke("callParentPublicMethod", false);
}
@Test
public void publicMethod_test_true() throws Exception {
A spy = PowerMockito.spy(new A());
spy.publicMethod(true);
PowerMockito.verifyPrivate(spy).invoke("privateMethod");
PowerMockito.verifyPrivate(spy).invoke("callParentPublicMethod", true);
}
}
希望对您有所帮助。
我有如下一段代码
public class A extends B {
private boolean workDone = false;
@Override
public void publicMethod(boolean flag) {
if (!workDone) {
privateMethod();
workDone = true;
}
super.publicMethod(flag);
}
private void privateMethod() {
// some logic here
}
}
我是模拟新手。我有以下疑问。我正在尝试测试 public 方法。
- 我可以断言私有变量 workDone 的值吗?
- 是否可以验证super中的方法调用class?
- 如何模拟方法中的私有方法调用?
在进行单元测试时,我们会验证public被测代码的可观察行为。这是 CUT 传送的return 值 及其与依赖项 的 通信
CUT 中的私有变量和私有方法是 实现细节 我们不想(明确地)测试,因为我们希望它们可以在不中断测试的情况下改变。
在极少数情况下,对超级 class 方法的调用可以被视为 "communication with dependency"。在这种情况下,您创建了 CUT 的 spy()
。但通常这也应该被视为 实施细节 ...
- 没有。私有变量只能通过反射访问。这通常不是首选,尤其是在单元测试中。
- 是的,假设您对超级 class 方法调用进行了一些可断言的更改。喜欢
boolean flag
中的变化
- 是的,您可以使用 powermockito。有关更多信息,请参见此处。 Testing Private method using mockito
如果你真的想验证它,你需要改变你的A class 并将超级调用提取到私有方法中:
public class A extends B {
private boolean workDone = false;
@Override
public void publicMethod(final boolean flag) {
if (!workDone) {
privateMethod();
workDone = true;
}
callParentPublicMethod(flag);
}
private void callParentPublicMethod(final boolean flag) {
super.publicMethod(flag);
}
private void privateMethod() {
System.out.println("A: privateMethodCalled");
}
}
完成此操作后,您可以使用 PowerMock 来验证私有方法调用:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ A.class })
public class ATest {
@Test
public void publicMethod_test_false() throws Exception {
A spy = PowerMockito.spy(new A());
spy.publicMethod(false);
PowerMockito.verifyPrivate(spy).invoke("privateMethod");
PowerMockito.verifyPrivate(spy).invoke("callParentPublicMethod", false);
}
@Test
public void publicMethod_test_true() throws Exception {
A spy = PowerMockito.spy(new A());
spy.publicMethod(true);
PowerMockito.verifyPrivate(spy).invoke("privateMethod");
PowerMockito.verifyPrivate(spy).invoke("callParentPublicMethod", true);
}
}
希望对您有所帮助。