Java 你能用Mockito模拟一个调用静态方法的非静态方法吗?
我知道你不能用mockito模拟静态方法。但是我试图模拟的方法不是静态的,但是它在其中调用了静态方法。那么我可以嘲笑这个方法吗 我在运行测试时遇到异常。对静态方法的调用是否是此异常的原因 要测试的类:Java 你能用Mockito模拟一个调用静态方法的非静态方法吗?,java,unit-testing,mocking,tdd,mockito,Java,Unit Testing,Mocking,Tdd,Mockito,我知道你不能用mockito模拟静态方法。但是我试图模拟的方法不是静态的,但是它在其中调用了静态方法。那么我可以嘲笑这个方法吗 我在运行测试时遇到异常。对静态方法的调用是否是此异常的原因 要测试的类: public class MyAction{ public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse re
public class MyAction{
public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
MyService service = new MyService();
**form.setList(service.getRecords(searchRequest));**
}
}
public class MyService{
public List getRecords(SearchRequest sr){
List returnList = new ArrayList();
MyDao dao = DAOFactory.getInstance().getDAO();---->Call to static method
// Some codes
return returnList;
}
}
public class DAOFactory{
private static DAOFactory instance = new DAOFactory();
public static DAOFactory getInstance() {------> The static method
return instance;
}
}
@Test
public void testSearch() throws Exception{
MyService service = mock(MyService.class);
MyAction action = new MyAction();
List<MyList> list = new ArrayList<MyList>();
when(service.getRecords(searchRequest)).thenReturn(list);
ActionForward forward = action.search(mapping, form, request, response);
}
模拟类和方法:
public class MyAction{
public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
MyService service = new MyService();
**form.setList(service.getRecords(searchRequest));**
}
}
public class MyService{
public List getRecords(SearchRequest sr){
List returnList = new ArrayList();
MyDao dao = DAOFactory.getInstance().getDAO();---->Call to static method
// Some codes
return returnList;
}
}
public class DAOFactory{
private static DAOFactory instance = new DAOFactory();
public static DAOFactory getInstance() {------> The static method
return instance;
}
}
@Test
public void testSearch() throws Exception{
MyService service = mock(MyService.class);
MyAction action = new MyAction();
List<MyList> list = new ArrayList<MyList>();
when(service.getRecords(searchRequest)).thenReturn(list);
ActionForward forward = action.search(mapping, form, request, response);
}
使用静态方法初始化:
public class MyAction{
public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
MyService service = new MyService();
**form.setList(service.getRecords(searchRequest));**
}
}
public class MyService{
public List getRecords(SearchRequest sr){
List returnList = new ArrayList();
MyDao dao = DAOFactory.getInstance().getDAO();---->Call to static method
// Some codes
return returnList;
}
}
public class DAOFactory{
private static DAOFactory instance = new DAOFactory();
public static DAOFactory getInstance() {------> The static method
return instance;
}
}
@Test
public void testSearch() throws Exception{
MyService service = mock(MyService.class);
MyAction action = new MyAction();
List<MyList> list = new ArrayList<MyList>();
when(service.getRecords(searchRequest)).thenReturn(list);
ActionForward forward = action.search(mapping, form, request, response);
}
我的测试:
public class MyAction{
public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
MyService service = new MyService();
**form.setList(service.getRecords(searchRequest));**
}
}
public class MyService{
public List getRecords(SearchRequest sr){
List returnList = new ArrayList();
MyDao dao = DAOFactory.getInstance().getDAO();---->Call to static method
// Some codes
return returnList;
}
}
public class DAOFactory{
private static DAOFactory instance = new DAOFactory();
public static DAOFactory getInstance() {------> The static method
return instance;
}
}
@Test
public void testSearch() throws Exception{
MyService service = mock(MyService.class);
MyAction action = new MyAction();
List<MyList> list = new ArrayList<MyList>();
when(service.getRecords(searchRequest)).thenReturn(list);
ActionForward forward = action.search(mapping, form, request, response);
}
@测试
public void testSearch()引发异常{
MyService=mock(MyService.class);
MyAction动作=新的MyAction();
列表=新的ArrayList();
when(service.getRecords(searchRequest)),然后return(list);
ActionForward=action.search(映射、表单、请求、响应);
}
这是我运行测试时的堆栈跟踪。请记住,为了简单起见,我已经更改了类的名称。
问题在于,您的
搜索
方法无法使用服务模拟,因为它通过MyService service=new MyClass()创建自己的实例代码>。因此,您必须重构MyAction
类,以允许MyService
注入并在其中注入模拟。或者使用更重的武器-PowerMock
最简单、最安全的重构
在IDE“extract method”重构中使用以提取构造“new MyClass()”。因此,它将成为:
public class MyAction{
public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
MyService service = getMyService();
**form.setList(service.getRecords(searchRequest));**
}
MyService getMyService() {
return new MyClass();
}
}
然后在单元测试中,您可以通过创建内部子类来注入模拟:
public class MyActionTest {
private MyService service = mock(MyService.class);
private MyAction action = new MyAction(){
@Override
MyService getMyService() {return service;}
};
@Test
public void testSearch() throws Exception{
List<MyList> list = new ArrayList<MyList>();
when(service.getRecords(searchRequest)).thenReturn(list);
ActionForward forward = action.search(mapping, form, request, response);
}
}
公共类MyActionTest{
私有MyService=mock(MyService.class);
private MyAction=new MyAction(){
@凌驾
MyService getMyService(){return service;}
};
@试验
public void testSearch()引发异常{
列表=新的ArrayList();
when(service.getRecords(searchRequest)),然后return(list);
ActionForward=action.search(映射、表单、请求、响应);
}
}
Doh-我一直在寻找更复杂的情况,完全忽略了服务模拟未使用的事实…@JonSkeet He。。。他是一名学生……:)尽管重构目前不是一个选项,因为我被要求为一些遗留代码编写测试,但我如何重构它以便注入模拟代码?Thanks@javaStudent我已将其中一种方法添加到我的answer@javaStudent一个被模拟的方法根本不会被执行,所以它对什么都不重要。