0

、mockito を使用してスプリング コントローラーを呼び出す方法を見てきました。

Mock を使用して、Spring MVC コントローラーを呼び出します。コントローラ Spring サービス クラスを呼び出します。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
public class TestController {


    @Mock
    private TestService testService;

    @InjectMocks
    private PaymentTransactionController paymentController;

    private MockMvc mockMvc;


     @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        this.setMockMvc(MockMvcBuilders.standaloneSetup(paymentController).build());
    }

    @Test
    public void test() throws Exception {
        this.mockMvc.perform(post("/tr/test").content(...)).andExpect(status().isOk());
        // testService.save(); <-- another way
    }

わかりました、うまくいきます。私は自分の Spring コントローラーを非常によく呼び出します。しかし、Springコントローラーでは、サービスレイヤーを注入しました。

@Autowired
private TestService serviceTest;


@RequestMapping(value = "/test", method = RequestMethod.POST)
@ResponseBody()
public String test(HttpServletRequest request) {
   ...
    serviceTest.save(); 
   // in save method I call dao and dao perist data;
   // I have injected dao intrface in serviceTest layer
   ...
   return result;

}

問題は、私のアプリが save メソッドを呼び出さず、そこに入力されていないことです。私もエラーはありません。Junit から save() メソッドを呼び出した場合も同じ結果になります (test() メソッドでコメントしました)。

デバッグすると、org.mockito.internal.creation.MethodInterceptorFilter の割り込みメソッドが発生することがわかりました。

この問題を解決するには?何が起こるのですか?

4

3 に答える 3

2

コントローラーの単体テストを行っている場合は、サービス レイヤーをモックする必要があります (何を行っているか)。この種のテストでは、それを制御するだけです:

  • コントローラーの正しいメソッドがトリガーされ、期待されるものが生成されます
  • サービス層の正しいメソッドが呼び出されます...モックで

モックのメソッドの戻り値を構成するか (関連する場合)、呼び出されたものを制御するだけです。

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    this.setMockMvc(MockMvcBuilders.standaloneSetup(paymentController).build());
    // set return values from the mocked service
    when(testService.find(1)).thenReturn(...);
}

後で何が呼び出されたかを確認します

@Test
public void test() throws Exception {
    this.mockMvc.perform(post("/tr/test").content(...)).andExpect(status().isOk());
    // testService.save(); <-- another way
    verify(testService, times(1)).save();
}

統合テストを実行する場合は、サービスをモックするのではなく、実際の Bean を注入するアプリケーション コンテキストをセットアップしますが、通常は実際の Bean の代わりに組み込みデータベースを使用します。

于 2014-10-22T15:23:43.000 に答える
0

私が理解しているように、「/tr/test」リソースへのポストを実行しますが、コントローラーのリクエスト マッピングは「/payment」です。コントローラーでマップされたリソースに必ず投稿してください。

于 2014-10-22T14:05:18.160 に答える