3

我知道你不能使用 mockito 来模拟静态方法。但是我试图模拟的方法不是静态的,但它调用了静态方法。那么我可以模拟这个方法吗?

运行测试时出现异常。对静态方法的调用是此异常的原因吗?

要测试的类:

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);        
}

这是我运行测试时的堆栈跟踪。请记住,为简单起见,我更改了类的名称。 在此处输入图像描述

4

1 回答 1

6

问题是您的search方法不能使用服务模拟,因为它通过MyService service = new MyClass();. 因此,您必须重构MyAction该类以允许MyService注入并在其中注入一个模拟。或者使用更重的武器——PowerMock。

最简单、最安全的重构

在您的 IDE 中使用“提取方法”重构来提取构造“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);        
    }

}
于 2013-01-24T20:48:12.843 回答