現在、Spring MVCベースのWebアプリケーションを作成しています。Mockito/Spring MVC - (アノテーション駆動型)リクエストマッピングの動的検証
注釈付きメソッドごとに1つのテストを書くのではなく、Parameterized JUnitランナーの恩恵を受けたいと思います。
最後に、私は私のコントローラメソッドで自分のラッパー対応へのすべてのプリミティブの引数を変更する(し、手動でヌルレフリーの健全性チェックを行う)しなければならなかったが、それはほとんど、働いて得ました。次のカスタムクラスMethodArgumentと
@RunWith(Parameterized.class)
public class MyControllerMappingTest {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private MyController mockedController;
private AnnotationMethodHandlerAdapter annotationHandlerAdapter;
private final String httpMethod;
private final String uri;
private final String controllerMethod;
private final Class<?>[] parameterTypes;
private final Object[] parameterValues;
@Before
public void setup() {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
mockedController = mock(MyController.class);
annotationHandlerAdapter = new AnnotationMethodHandlerAdapter();
}
@Parameters
public static Collection<Object[]> requestMappings() {
return asList(new Object[][] {
{"GET", "/my/uri/0", "index", arguments(new MethodArgument(Integer.class, 0))}
});
}
private static List<MethodArgument> arguments(MethodArgument... arguments) {
return asList(arguments);
}
public MyControllerMappingTest(String httpMethod, String uri, String controllerMethod, List<MethodArgument> additionalParameters) {
this.httpMethod = httpMethod;
this.uri = uri;
this.controllerMethod = controllerMethod;
this.parameterTypes = new Class<?>[additionalParameters.size()];
initializeParameterTypes(additionalParameters);
this.parameterValues = newArrayList(transform(additionalParameters, valueExtractor())).toArray();
}
private void initializeParameterTypes(List<MethodArgument> additionalParameters) {
Iterable<Class<?>> classes = transform(additionalParameters, typeExtractor());
int i = 0;
for (Class<?> parameterClass : classes) {
parameterTypes[i++] = parameterClass;
}
}
@Test
public void when_matching_mapping_constraints_then_controller_method_automatically_called() throws Exception {
request.setMethod(httpMethod);
request.setRequestURI(uri);
annotationHandlerAdapter.handle(request, response, mockedController);
Method method = MyController.class.getMethod(controllerMethod, parameterTypes);
method.invoke(verify(mockedController), parameterValues);
}
}
:
それは助けることができる場合は、ここでのコード(これはまた、グアバに依存)である
public class MethodArgument {
private final Class<?> type;
private final Object value;
public MethodArgument(final Class<?> type, final Object value) {
this.type = type;
this.value = value;
}
public Object getValue() {
return value;
}
public Class<?> getType() {
return type;
}
public static Function<MethodArgument, Class<?>> typeExtractor() {
return new Function<MethodArgument, Class<?>>() {
@Override
public Class<?> apply(MethodArgument argument) {
return argument.getType();
}
};
}
public static Function<MethodArgument, Object> valueExtractor() {
return new Function<MethodArgument, Object>() {
@Override
public Object apply(MethodArgument argument) {
return argument.getValue();
}
};
}
}
をので、私はほとんどそこです、ここでの唯一のテストケースはJava Integerキャッシュのために機能し、したがってIntegerインスタンスは呼び出しチェーン全体で同じです...これはカスタムオブジェクトでは機能しませんが、私はいつもInvocationTargetExceptionで終わります(原因: "Argument (複数可)は違います!」)...
タイプは正しいですが、渡されたインスタンスは@Parametersメソッドで設定されたものと同じではありません。
これを回避する方法はありますか?
私はPiwai(私は彼にIRL ^^を知っている)で説明したように、私の最初のアプローチは間違っている...与えられたHTTPリクエストがルーティングされていることをテストします特定の方法への実装の問題です... したがって、私が欲しいものを機能的にテストする最も適切な方法は、実際の要求を送信/シミュレートし、返された応答内容を確認することです。簡単に言えば、これは私が正しい方向に向いているので、この答えを受け入れるでしょう:) – Rolf
そして私はあなたを認識しませんでした-_- ' こんにちは! :) – Rolf