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 に答える