Java 如何验证已使用 power mockito 调用了静态 void 方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18466198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to verify static void method has been called with power mockito
提问by Chun ping Wang
I am using the following.
我正在使用以下内容。
Powermock-mockito 1.5.12
Mockito 1.95
junit 4.11
Here is my utils class
这是我的 utils 类
public void InternalUtils {
public static void sendEmail(String from, String[] to, String msg, String body) {
}
}
here is gist of the class under test:
这是被测课程的要点:
public class InternalService {
public void processOrder(Order order) {
if (order.isSuccessful()) {
InternalUtils.sendEmail(...);
}
}
}
And here is the test:
这是测试:
@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);
}
}
The above test fails. The verification mode given is none, but according to the code, if order is successful than email must be send.
上述测试失败。给出的验证方式是无,但根据代码,如果订单成功,则必须发送电子邮件。
采纳答案by Matt Lachman
If you are mocking the behavior (with something like doNothing()
) there should really be no need to call to verify*()
. That said, here's my stab at re-writing your test method:
如果您正在嘲笑行为(类似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());
}
}
I grouped into four sections to better highlight what is going on:
我分为四个部分,以更好地强调正在发生的事情:
1. Variables
1. 变量
I choose to declare any instance variables / method arguments / mock collaborators here. If it is something used in multiple tests, consider making it an instance variable of the test class.
我选择在这里声明任何实例变量/方法参数/模拟合作者。如果它在多个测试中使用,请考虑将其设为测试类的实例变量。
2. Mock Behavior
2. 模拟行为
This is where you define the behavior of all of your mocks. You're setting up return values and expectations here, prior to executing the code under test. Generally speaking, if you set the mock behavior here you wouldn't need to verify the behavior later.
这是您定义所有模拟的行为的地方。在执行被测代码之前,您在此处设置返回值和期望值。一般来说,如果您在此处设置模拟行为,则稍后无需验证该行为。
3. Execute
3. 执行
Nothing fancy here; this just kicks off the code being tested. I like to give it its own section to call attention to it.
这里没什么好看的;这只是启动正在测试的代码。我喜欢给它自己的部分来引起人们的注意。
4. Verify
4. 验证
This is when you call any method starting with verify
or assert
. After the test is over, you check that the things you wanted to have happen actually did happen. That is the biggest mistake I see with your test method; you attempted to verify the method call before it was ever given a chance to run. Second to that is you never specified whichstatic method you wanted to verify.
这是当您调用以verify
或开头的任何方法时assert
。测试结束后,您检查您希望发生的事情是否确实发生了。这是我在您的测试方法中看到的最大错误;您试图在方法调用有机会运行之前对其进行验证。第二到是你从来没有指定哪个你想验证静态方法。
Additional Notes
补充说明
This is mostly personal preference on my part. There is a certain order you need to do things in but within each grouping there is a little wiggle room. This helps me quickly separate out what is happening where.
这主要是我个人的喜好。你需要按照一定的顺序做事,但在每个分组内都有一点回旋余地。这有助于我快速分辨出在哪里发生了什么。
I also highly recommend going through the examples at the following sites as they are very robust and can help with the majority of the cases you'll need:
我还强烈建议您阅读以下网站上的示例,因为它们非常强大,可以帮助您解决大多数情况:
- https://github.com/powermock/powermock/wiki/Mockito(PowerMock Overview / Examples)
- http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html(Mockito Overview / Examples)
回答by Arpit
Thou the above answer is widely accepted and well documented, I found some of the reason to post my answer here :-
你上面的答案被广泛接受并且有据可查,我找到了在这里发布我的答案的一些原因:-
doNothing().when(InternalUtils.class); //This is the preferred way
//to mock static void methods.
InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());
Here, I dont understand why we are calling InternalUtils.sendEmail ourself. I will explain in my code why we don't need to do that.
在这里,我不明白为什么我们自己调用 InternalUtils.sendEmail。我将在我的代码中解释为什么我们不需要这样做。
mockStatic(Internalutils.class);
So, we have mocked the class which is fine. Now, lets have a look how we need to verify the sendEmail(/..../) method.
所以,我们嘲笑了这个很好的类。现在,让我们看看我们需要如何验证 sendEmail(/..../) 方法。
@PrepareForTest({InternalService.InternalUtils.class})
@RunWith(PowerMockRunner.class)
public class InternalServiceTest {
@Mock
private InternalService.Order order;
private InternalService internalService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
internalService = new InternalService();
}
@Test
public void processOrder() throws Exception {
Mockito.when(order.isSuccessful()).thenReturn(true);
PowerMockito.mockStatic(InternalService.InternalUtils.class);
internalService.processOrder(order);
PowerMockito.verifyStatic(times(1));
InternalService.InternalUtils.sendEmail(anyString(), any(String[].class), anyString(), anyString());
}
}
These two lines is where the magic is, First line tells the PowerMockito framework that it needs to verify the class it statically mocked. But which method it need to verify ?? Second line tells which method it needs to verify.
这两行是神奇的地方,第一行告诉 PowerMockito 框架它需要验证它静态模拟的类。但是它需要验证哪种方法??第二行告诉它需要验证哪种方法。
PowerMockito.verifyStatic(times(1));
InternalService.InternalUtils.sendEmail(anyString(), any(String[].class), anyString(), anyString());
This is code of my class, sendEmailapi twice.
这是我班级的代码,两次sendEmailapi。
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;
}
}
}
As it is calling twice you just need to change the verify(times(2))... that's all.
由于它调用了两次,您只需要更改 verify(times(2)) ......就是这样。