@Test public void resolveArgumentNoMatch() throws Exception { MultiValueMap<String, String> params2 = getMatrixVariables("planes"); params2.add("colors", "yellow"); params2.add("colors", "orange"); MethodParameter param = this.testMethod.annot(matrixAttribute().pathVar("cars")) .arg(MultiValueMap.class, String.class, String.class); @SuppressWarnings("unchecked") Map<String, String> map = (Map<String, String>) this.resolver.resolveArgument( param, new BindingContext(), this.exchange).block(Duration.ZERO); assertEquals(Collections.emptyMap(), map); }
@Test public void invocationTargetException() { Method method = ResolvableMethod.on(TestController.class).mockCall(TestController::exceptionMethod).method(); Mono<HandlerResult> mono = invoke(new TestController(), method); try { mono.block(); fail("Expected IllegalStateException"); } catch (IllegalStateException ex) { assertThat(ex.getMessage(), is("boo")); } }
@Test public void createAndBindToMono() throws Exception { MethodParameter parameter = this.testMethod .annotNotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); testBindFoo("fooMono", parameter, mono -> { assertTrue(mono.getClass().getName(), mono instanceof Mono); Object value = ((Mono<?>) mono).block(Duration.ofSeconds(5)); assertEquals(Foo.class, value.getClass()); return (Foo) value; }); }
@Test public void supportsParameter() { assertFalse(this.resolver.supportsParameter(this.testMethod.arg(String.class))); assertTrue(this.resolver.supportsParameter(this.testMethod .annot(matrixAttribute().noName()).arg(List.class, String.class))); assertTrue(this.resolver.supportsParameter(this.testMethod .annot(matrixAttribute().name("year")).arg(int.class))); }
@Test public void supportsParameter() throws Exception { assertTrue(this.resolver.supportsParameter( this.testMethod.annot(requestAttribute().noName()).arg(Foo.class))); // SPR-16158 assertTrue(this.resolver.supportsParameter( this.testMethod.annotPresent(RequestAttribute.class).arg(Mono.class, Foo.class))); assertFalse(this.resolver.supportsParameter( this.testMethod.annotNotPresent(RequestAttribute.class).arg())); }
@Test // SPR-14877 public void handleMonoWithWildcardBodyType() throws Exception { MockServerWebExchange exchange = MockServerWebExchange.from(get("/path")); exchange.getAttributes().put(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Collections.singleton(APPLICATION_JSON)); MethodParameter type = on(TestController.class).resolveReturnType(Mono.class, ResponseEntity.class); HandlerResult result = new HandlerResult(new TestController(), Mono.just(ok().body("body")), type); this.resultHandler.handleResult(exchange, result).block(Duration.ofSeconds(5)); assertEquals(HttpStatus.OK, exchange.getResponse().getStatusCode()); assertResponseBody(exchange, "body"); }
@Test public void createAndBind() throws Exception { testBindFoo("foo", this.testMethod.annotPresent(ModelAttribute.class).arg(Foo.class), value -> { assertEquals(Foo.class, value.getClass()); return (Foo) value; }); }
@SuppressWarnings("unchecked") private <T> T resolveValue(ServerWebExchange exchange, ResolvableType type) { MethodParameter param = this.testMethod.arg(type); Mono<Object> result = this.resolver.resolveArgument(param, new BindingContext(), exchange); Object value = result.block(Duration.ofSeconds(5)); assertNotNull(value); assertTrue("Unexpected return value type: " + value.getClass(), param.getParameterType().isAssignableFrom(value.getClass())); return (T) value; }
@Test public void supports() throws Exception { MethodParameter param; param = this.testMethod.annot(requestBody()).arg(Mono.class, String.class); assertTrue(this.resolver.supportsParameter(param)); param = this.testMethod.annotNotPresent(RequestBody.class).arg(String.class); assertFalse(this.resolver.supportsParameter(param)); }
@Test public void supports() throws Exception { ModelAttributeMethodArgumentResolver resolver = new ModelAttributeMethodArgumentResolver(ReactiveAdapterRegistry.getSharedInstance(), false); MethodParameter param = this.testMethod.annotPresent(ModelAttribute.class).arg(Foo.class); assertTrue(resolver.supportsParameter(param)); param = this.testMethod.annotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); assertTrue(resolver.supportsParameter(param)); param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Foo.class); assertFalse(resolver.supportsParameter(param)); param = this.testMethod.annotNotPresent(ModelAttribute.class).arg(Mono.class, Foo.class); assertFalse(resolver.supportsParameter(param)); }
private String formatMethod() { return (method().getName() + Arrays.stream(this.method.getParameters()) .map(this::formatParameter) .collect(joining(",\n\t", "(\n\t", "\n)"))); }
/** * Resolve and return the declared return type equivalent to: * <p>{@code build().returnType()} */ public final MethodParameter resolveReturnType() { return build().returnType(); }
/** * Build a {@code ResolvableMethod} from the provided filters which must * resolve to a unique, single method. * <p>See additional resolveXxx shortcut methods going directly to * {@link Method} or return type parameter. * @throws IllegalStateException for no match or multiple matches */ public ResolvableMethod build() { Set<Method> methods = MethodIntrospector.selectMethods(this.objectClass, this::isMatch); Assert.state(!methods.isEmpty(), () -> "No matching method: " + this); Assert.state(methods.size() == 1, () -> "Multiple matching methods: " + this + formatMethods(methods)); return new ResolvableMethod(methods.iterator().next()); }
@Override public String toString() { return "ResolvableMethod=" + formatMethod(); }
@Test public void supportsParameter() { assertFalse(this.resolver.supportsParameter(this.testMethod.arg(String.class))); assertTrue(this.resolver.supportsParameter( this.testMethod.annot(matrixAttribute().noName()).arg(List.class, String.class))); assertTrue(this.resolver.supportsParameter( this.testMethod.annot(matrixAttribute().name("year")).arg(int.class))); }
@Test public void supportsParameter() { MethodParameter param = this.testMethod.annot(requestParam().noName()).arg(Map.class, String.class, String.class); assertTrue(resolver.supportsParameter(param)); param = this.testMethod.annotPresent(RequestParam.class).arg(MultiValueMap.class, String.class, String.class); assertTrue(resolver.supportsParameter(param)); param = this.testMethod.annot(requestParam().name("name")).arg(Map.class, String.class, String.class); assertFalse(resolver.supportsParameter(param)); param = this.testMethod.annotNotPresent(RequestParam.class).arg(Map.class, String.class, String.class); assertFalse(resolver.supportsParameter(param)); }
@Test public void doesNotSupportReturnTypes() throws Exception { assertFalse(this.handler.supportsReturnType( on(TestController.class).resolveReturnType(ResponseEntity.class, String.class))); assertFalse(this.handler.supportsReturnType( on(TestController.class).resolveReturnType(forClassWithGenerics(ResponseEntity.class, forClassWithGenerics(AtomicReference.class, String.class))))); assertFalse(this.handler.supportsReturnType( on(TestController.class).resolveReturnType(ResponseEntity.class))); }
@Test public void createAndBindToSingle() throws Exception { MethodParameter parameter = this.testMethod .annotPresent(ModelAttribute.class).arg(Single.class, Foo.class); testBindFoo("fooSingle", parameter, single -> { assertTrue(single.getClass().getName(), single instanceof Single); Object value = ((Single<?>) single).toBlocking().value(); assertEquals(Foo.class, value.getClass()); return (Foo) value; }); }
@Test // SPR-16187 public void resolveWithBindingResultNotFound() { this.expectedException.expectMessage("An Errors/BindingResult argument is expected " + "immediately after the @ModelAttribute argument"); MethodParameter parameter = this.testMethod.arg(Errors.class); this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange) .block(Duration.ofMillis(5000)); }
/** * Resolve and return the {@code Method} equivalent to: * <p>{@code build().method()} */ public final Method resolveMethod() { return build().method(); }