Java 如何验证已使用power mockito调用静态void方法
我正在使用以下命令Java 如何验证已使用power mockito调用静态void方法,java,unit-testing,mockito,static-methods,Java,Unit Testing,Mockito,Static Methods,我正在使用以下命令 Powermock-mockito 1.5.12 Mockito 1.95 junit 4.11 这是我的utils课程 public void InternalUtils { public static void sendEmail(String from, String[] to, String msg, String body) { } } 以下是被测课程的要点: public class InternalService { publi
Powermock-mockito 1.5.12
Mockito 1.95
junit 4.11
这是我的utils课程
public void InternalUtils {
public static void sendEmail(String from, String[] to, String msg, String body) {
}
}
以下是被测课程的要点:
public class InternalService {
public void processOrder(Order order) {
if (order.isSuccessful()) {
InternalUtils.sendEmail(...);
}
}
}
下面是测试:
@PrepareForTest({InternalUtils.class})
@RunWith(PowerMockRunner.class)
public class InternalService {
public void verifyEmailSend() {
mockStatic(Internalutils.class);
doNothing().when(InternalUtils, "sendEmail", anyString(), any(String.class), anyString(), anyString());
Order order = mock(Order.class);
when(order.isSuccessful()).thenReturn(true);
InternalService is = new InternalService();
verifyStatic(times(1));
is.processOrder(order);
}
}
上述测试失败。给出的验证模式为无,但根据代码,如果订单成功,则必须发送电子邮件 如果您正在模拟行为(使用类似于
doNothing()
)的东西),那么实际上就不需要调用verify*()
。也就是说,我尝试重新编写您的测试方法:
@PrepareForTest({InternalUtils.class})
@RunWith(PowerMockRunner.class)
public class InternalServiceTest { //Note the renaming of the test class.
public void testProcessOrder() {
//Variables
InternalService is = new InternalService();
Order order = mock(Order.class);
//Mock Behavior
when(order.isSuccessful()).thenReturn(true);
mockStatic(Internalutils.class);
doNothing().when(InternalUtils.class); //This is the preferred way
//to mock static void methods.
InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());
//Execute
is.processOrder(order);
//Verify
verifyStatic(InternalUtils.class); //Similar to how you mock static methods
//this is how you verify them.
InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());
}
}
我将其分为四个部分,以更好地强调正在发生的事情:
1.变量
我选择在这里声明任何实例变量/方法参数/模拟协作者。如果它是在多个测试中使用的,请考虑将其作为测试类的实例变量。
2.模仿行为
这是定义所有模拟的行为的地方。在执行测试代码之前,在这里设置返回值和期望值。一般来说,如果您在这里设置模拟行为,那么以后就不需要验证该行为
3.执行
这里没有什么特别的东西;这只是启动正在测试的代码。我想给它自己的部分,以提请注意它
4.验证
这是在调用任何以verify
或assert
开头的方法时发生的。测试结束后,您检查希望发生的事情是否确实发生了。这是我在你的测试方法中看到的最大错误;您试图在方法调用有机会运行之前验证它。其次,您从未指定要验证的静态方法
PowerMockito.verifyStatic(times(1));
InternalService.InternalUtils.sendEmail(anyString(), any(String[].class), anyString(), anyString());
附加说明
这主要是我个人的偏好。有一个特定的顺序,你需要做的事情,但在每个分组有一个小回旋余地。这有助于我快速区分发生在哪里的事情
我还强烈建议浏览以下站点的示例,因为它们非常强大,可以帮助您处理大多数需要的案例:
- (PowerMock概述/示例)
- (Mockito概述/示例)
doNothing().when(InternalUtils.class); //This is the preferred way
//to mock static void methods.
InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());
在这里,我不明白为什么我们要自己调用InternalUtils.sendmail。
我将在我的代码中解释为什么我们不需要这样做
mockStatic(Internalutils.class);
所以,我们嘲笑了这个班,这很好。
现在,让我们看看需要如何验证sendmail(/…../)方法
这两条线就是魔力所在,
第一行告诉PowerMockito框架它需要验证它静态模拟的类。但它需要验证哪种方法??
第二行说明需要验证的方法
PowerMockito.verifyStatic(times(1));
InternalService.InternalUtils.sendEmail(anyString(), any(String[].class), anyString(), anyString());
这是我的类代码,sendmailapi两次
public class InternalService {
public void processOrder(Order order) {
if (order.isSuccessful()) {
InternalUtils.sendEmail("", new String[1], "", "");
InternalUtils.sendEmail("", new String[1], "", "");
}
}
public static class InternalUtils{
public static void sendEmail(String from, String[] to, String msg, String body){
}
}
public class Order{
public boolean isSuccessful(){
return true;
}
}
}
由于它调用了两次,您只需更改验证(次数(2))。。。仅此而已。verifyStatic(次(1));==verifyStatic();确实如此:我试图验证返回void的静态方法是否只调用了一次(使用一些特定参数)。我必须从上面的代码中删除doNothing语句才能使其正常工作。我如何检查某个特定的静态方法是否调用了两次,而另一个方法是否调用了一次?@ganeshstate您将执行
verifyStatic()
调用两次,第一个方法调用一次(然后是第一个方法调用)对于第二个方法(后面是第二个方法调用)。对于被调用两次的方法,将times(2)
传递到verifyStatic()
。