4

私の問題はこれらに似ています:

しかし

コントローラー メソッドのシグネチャが与えられた場合:

public String setupForm(
    @ModelAttribute("notification") Notification n, RedirectAttributes redirect)

そして、(Mockitoを使用して)テストが与えられます:

@Mock
private AddNotificationController handler;
@Test
public void get() throws Exception{
    request.setRequestURI("/addNotification/save.do");
    request.setMethod("GET");
    adapter.handle(request, response, handler);
    verify(handler,times(1)).setupForm(any(Notification.class), any(RedirectAttributes.class));
  }

そして、実行時に例外が発生しました:

org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: 
Failed to invoke handler method [public java.lang.String ep.rdp.web.AddNotificationController.setupForm(a.b.c.Notification,org.springframework.web.servlet.mvc.support.RedirectAttributes)]; 
nested exception is java.lang.IllegalStateException: 
Argument [RedirectAttributes] is of type Model or Map but is not assignable from the actual model. 
You may need to switch newer MVC infrastructure classes to use this argument.

実際、私は問題を知っており、スプリングを適切に設定することで解決する方法を知っていますが、単体テストではありません。

質問: モックを機能させるには、他に何をセットアップする必要がありますか?

追加情報

モックの基本設定:

  @Before
  public void setup() {
//    adapter = new AnnotationMethodHandlerAdapter();
    adapter = new RequestMappingHandlerAdapter();
    request = new MockHttpServletRequest();
    /*
     * needed for AnnotationMethodHandlerAdapter when resolving controlle level mapping
     */
    request.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING, Boolean.TRUE);
    response = new MockHttpServletResponse();
  }

実際に

  • AnnotationMethodHandlerAdapter を使用すると、この症状が発生します。
  • RequestMappingHandlerAdapter を使用すると、次のようになりました。

    java.lang.ClassCastException: ep.rdp.web.CacheController$$EnhancerByMockitoWithCGLIB$$d8aab2c0 は org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter で org.springframework.web.method.HandlerMethod にキャストできません.java:80)

4

1 に答える 1

0

あなたの質問について何かが欠けているかもしれませんが、コントローラーのモックを作成してテストする理由がわかりません...春はリフレクションを使用してクラスコントローラーの注釈を読み取ろうとしますが、使用できませんあなたのモックに適切に反映してください。

マッピングをテストする正しい方法ではないと思います。Spring はこのモジュールを提供してコントローラーを単体テストし、すべてが提供されます。したがって、ここではモックを作成しないでください。実際のオブジェクトでメソッドをモックしたい場合は、@Spy (実際のオブジェクトに適用されるスパイ) かもしれません。

あなたがやろうとしているのは、次のようなものを作成することです:

@Before
public void setUp() {
    this.mockMvc = MockMvcBuilders
            .standaloneSetup(new AddNotificationController())
            .build();
}

// and your test
@Test
public void testYourMethodName() {
    this.mockMvc.perform(MockHttpServletRequestBuilder.get("/addNotification/save.do"))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andExpect(MockMvcResultMatchers.handler().method("yourMethodName"))
            .abdExpect(MockMvcResultMatchers.redirectedUrl("yourUrl"));
}

ご覧のとおり、mockito が提供するモック オブジェクトは使用していませんが、リクエストがメソッド「yourMethodName」によって処理されていることを確認しています。モックが必要な場合は、クラス AddNotificationController 内にある必要があります。したがって、このクラスで @InjectMock を使用し、ここでコントローラー内で使用される @Mock オブジェクトを作成します。これはおそらくうまくいくはずだと思います:

@Mock
public SomeService service;

@InjectMocks
public AddNotificationController controller = new AddNotificationController();

@Before
public void setUp() {
    this.mockMvc = MockMvcBuilders
            .standaloneSetup(this.controller)
            .build();
}

PS : 私の英語で申し訳ありません。

于 2014-02-01T18:49:13.023 に答える