自己写单元测试时的总结:
在类上添加
@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticTest.class})
方法:
PowerMockito.mockStatic(StaticTest.class);
PowerMockito.when(StaticTest.static1()).thenReturn("static"); // 方法的参数尽量一致
PowerMockito.doNothing().when(StaticTest.class, "static1", file, null);
String result = StaticTest.static1();
@InjectMocks
@Spy
private AccountInfoController fixture = new AccountInfoController();
@Mock
private AccountInfoService accountInfoService;
@Mock
private HttpServletRequest request;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
doReturn(map).when(accountInfoService).addAccountInfo("a", "user", 0, 1, "xxx", "opera", 1, 1);
File file = new File(path);
return file.exists();
模拟:
@RunWith(PowerMockRunner.class)
@PrepareForTest(必须是**待测试方法所在的类**.class)
File file = PowerMockito.mock(File.class);
PowerMockito.whenNew(File.class).withArguments("bbb").thenReturn(file);
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(file);
PowerMockito.whenNew(File.class).withAnyArguments().thenReturn(file);
PowerMockito.when(file.exists()).thenReturn(true);
注: 待测试方法的意思是: 比如测试A类中的methodB()方法,则prepareForTest里包含A.class, 而不是A的测试类
PowerMockito.doNothing().when(casService).addSupplier(anyLong(), any(ServiceKey.class));
BaseTransaction baseTransaction = Mockito.mock(BaseTransaction.class, Mockito.CALLS_REAL_METHODS);
@Mock与MockitoAnnotations.initMocks(this);
总结
8. Progress process = Mockito.mock(Progress.class); mock只是mock一个类/接口的对象,
mock出来的对象并不会自动替换掉正式代码里面的对象,你必须要有某种方式把mock对象应用到正式代码里面
9. PasswordValidator spyValidator = Mockito.spy(PasswordValidator.class);
Mockito.when(spyValidator.verifyPassword(anyString())).thenReturn(true);
10. spy与mock的唯一区别就是默认行为不一样:spy对象的方法默认调用真实的逻辑,mock对象的方法默认什么都不做,或直接返回默认值
如果mock的方法在多线程中, 则要在test方法中进行休眠处理,防止主线程结束导致多线程没有正常结束
PowerMockito.doThrow(new MySelfException("111")).when(object).method(Mockito.anyString(),Mockito.anyInt());
spy的对象也可以进行mock。mock的方法参数类型必须与实际参数一致,尤其注意null参数
Mockito.doNothing().when(fixture).addAccountInfo(Mockito.anyString(), Mockito.eq(null));
Field field = spy类.class.getDeclaredField("a");
field.setAccessible(true); //粗爆的改成可访问,不管现有修饰
field.set(spy对象, 3);
@PrepareForTest({A.class})
PowerMockito.doNothing().when(fixture, "method", Mockito.anyInt(), Mockito.anyString());
PowerMockito.doreturn(***).when(fixture, "method1", Mockito.anyInt(), Mockito.anyString());
private Method privateMethod;
@Before
public void setUp() throws Exception {
privateMethod = A.class.getDeclaredMethod("privateMethod", Integer.class, String.class);
privateMethod.setAccessible(true);
}
try {
privateMethod.invoke(fixture, 1, "1");
}catch (Exception e) {
if (e instanceof InvocationTargetException) {
InvocationTargetException e1 = (InvocationTargetException) e;
System.out.println(e1.getCause().getMessage());
} else {
System.out.println(e.getMessage());
}
}
PowerMockito.when(A.method1).thenReturn(result1).thenReturn(result2).thenReturn(result3);
Mockito.any(String[].class)
private HttpClient mockHttpClient;
private HttpPost mockHttpPost;
private HttpResponse mockHttpResponse;
private HttpEntity mockHttpEntity;
private InputStream mockInputStream;
private InputStreamReader mockInputStreamReader;
private BufferedReader mockBufferedReader;
ProtocolVersion protocolVersion = new ProtocolVersion("1", 2,1);
StatusLine statusLine = new BasicStatusLine(protocolVersion, 200, "");
PowerMockito.mockStatic(HttpClientBuilder.class);
PowerMockito.when(HttpClientBuilder.create()).thenReturn(mockHttpClientBuilder);
PowerMockito.doReturn(mockHttpClient).when(mockHttpClientBuilder).build();
PowerMockito.doReturn(mockHttpResponse).when(mockHttpClient).execute(Mockito.any(HttpPost.class));
PowerMockito.doReturn(statusLine).when(mockHttpResponse).getStatusLine();
PowerMockito.doThrow(new Exception("111")).when(a).method();
a. PowerMockito.doReturn(null).when(a).method();
b. PowerMockito.when(a.method()).thenReturn(null);
c. PowerMockito.doThrow(exception).when(mock).someVoidMethod();
d. PowerMockito.doReturn(null).when(a.method());
区别:
1. 首先mock对象需要花费时间。
2. 如果mock对象过程结束了,则三个方法可以随便调用,即在setup的方法(@Before)中先初始化mock对象,那么三个方法可以随意调用
3. 如果是在方法内部才开始mock对象,即(Power)Mockito.mock(A.class),那么最好是使用b或c的方法,能保证在mock对象结束后再返回结果,否则会提示UnfinishedStubbingException异常
4. 建议用b方法
5. a和d的区别是,如果a是spy的对象,需要用a
MockProducer mockProducer = PowerMockito.mock(MockProducer.class);
Field producer = AlertUtil.class.getDeclaredField("producer");
producer.setAccessible(true);
producer.set(AlertUtil.class, mockProducer);
PowerMockito.when(mockProducer.send(Mockito.any(ProducerRecord.class))).thenReturn(null);
a. 需要先创建,然后读取*
File file = new File(this.getClass().getResource("").getFile() + "fileName");
if (!file.exists()) {
generateFile(file);
} else {
file.delete();
generateFile(file);
}
FileInputStream fileInputStream = new FileInputStream(file);
PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenReturn(fileInputStream);
public void generateFile(File file) {
Document document = DocumentHelper.createDocument();
Element rootElement = document.addElement("allocations");
Element rootQueueElement = rootElement.addElement("queue");
rootQueueElement.addAttribute("name", "root");
Element aclSubmitApps = rootQueueElement.addElement("aclSubmitApps");
aclSubmitApps.addText(" ");
Element aclAdministerApps = rootQueueElement.addElement("aclAdministerApps");
aclAdministerApps.addText(" ");
Element queueChild = rootQueueElement.addElement("queue");
queueChild.addAttribute("name", "999");
queueChild.addElement("minResources").setText("1 mb,1 vcores");
queueChild.addElement("maxResources").setText("1 mb,1 vcores");
queueChild.addElement("maxRunningApps").setText("1");
queueChild.addElement("maxAMShare").setText("1");
queueChild.addElement("aclSubmitApps").setText("1");
queueChild.addElement("weight").setText("1");
queueChild.addElement("schedulingPolicy").setText("1");
XMLWriter writer = null;
try {
// 把内存中的dom树 写回到一个xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
// 指定XML编码 输出到output.xml
format.setEncoding("UTF-8");
format.setTrimText(false);
writer = new XMLWriter(new FileOutputStream(file), format);
writer.write(document);
writer.flush();
} catch (Exception e) {
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
}
}
}
}
b. 直接将文件写在内存中: 太费事,不好实现,暂时没想到好方法
a.只要是接口调用,都可以直接mock: PowerMockito.mock(A.class);
b.在一个测试方法中,mock方法是全方法有效,除非是改变方法的方法值,否则不需要再次调用;同理mock的对象也是在方法内一直有效。
c.若mock对象的方法没有设定返回值,那么返回的结果是默认值:单个对象返回的是null,集合返回的是大小为0的集合
d.mock静态类的时候,mockStatic()括号中的类一定要是static方法所在的类,否则可能出现问题(即使继承也不行);非static类可以
Connection connection = PowerMockito.mock(Connection.class);
Statement statement = PowerMockito.mock(Statement.class);
ResultSet resultSet = PowerMockito.mock(ResultSet.class);
PowerMockito.mockStatic(DBConnectUtil.class);
PowerMockito.when(DBConnectUtil.getConnection(null, null, null, null)).thenReturn(connection);
PowerMockito.when(connection.createStatement()).thenReturn(statement);
PowerMockito.when(statement.executeQuery(Mockito.anyString())).thenReturn(resultSet);
PowerMockito.when(resultSet.ne()).thenReturn(true).thenReturn(false);
PowerMockito.when(resultSet.getString(Mockito.anyInt())).thenReturn("1").thenReturn("2");