001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.servlet.htmlunit; 018 019import com.gargoylesoftware.htmlunit.WebClient; 020 021import org.springframework.lang.Nullable; 022import org.springframework.test.web.servlet.MockMvc; 023import org.springframework.test.web.servlet.setup.MockMvcConfigurer; 024import org.springframework.util.Assert; 025import org.springframework.web.context.WebApplicationContext; 026 027/** 028 * {@code MockMvcWebClientBuilder} simplifies the creation of an HtmlUnit 029 * {@link WebClient} that delegates to a {@link MockMvc} instance. 030 * 031 * <p>The {@code MockMvc} instance used by the builder may be 032 * {@linkplain #mockMvcSetup supplied directly} or created transparently 033 * from a {@link #webAppContextSetup WebApplicationContext}. 034 * 035 * @author Rob Winch 036 * @author Sam Brannen 037 * @since 4.2 038 * @see #mockMvcSetup(MockMvc) 039 * @see #webAppContextSetup(WebApplicationContext) 040 * @see #webAppContextSetup(WebApplicationContext, MockMvcConfigurer) 041 * @see #withDelegate(WebClient) 042 * @see #build() 043 */ 044public class MockMvcWebClientBuilder extends MockMvcWebConnectionBuilderSupport<MockMvcWebClientBuilder> { 045 046 @Nullable 047 private WebClient webClient; 048 049 050 protected MockMvcWebClientBuilder(MockMvc mockMvc) { 051 super(mockMvc); 052 } 053 054 protected MockMvcWebClientBuilder(WebApplicationContext context) { 055 super(context); 056 } 057 058 protected MockMvcWebClientBuilder(WebApplicationContext context, MockMvcConfigurer configurer) { 059 super(context, configurer); 060 } 061 062 063 /** 064 * Create a new {@code MockMvcWebClientBuilder} based on the supplied 065 * {@link MockMvc} instance. 066 * @param mockMvc the {@code MockMvc} instance to use; never {@code null} 067 * @return the MockMvcWebClientBuilder to customize 068 */ 069 public static MockMvcWebClientBuilder mockMvcSetup(MockMvc mockMvc) { 070 Assert.notNull(mockMvc, "MockMvc must not be null"); 071 return new MockMvcWebClientBuilder(mockMvc); 072 } 073 074 /** 075 * Create a new {@code MockMvcWebClientBuilder} based on the supplied 076 * {@link WebApplicationContext}. 077 * @param context the {@code WebApplicationContext} to create a {@link MockMvc} 078 * instance from; never {@code null} 079 * @return the MockMvcWebClientBuilder to customize 080 */ 081 public static MockMvcWebClientBuilder webAppContextSetup(WebApplicationContext context) { 082 Assert.notNull(context, "WebApplicationContext must not be null"); 083 return new MockMvcWebClientBuilder(context); 084 } 085 086 /** 087 * Create a new {@code MockMvcWebClientBuilder} based on the supplied 088 * {@link WebApplicationContext} and {@link MockMvcConfigurer}. 089 * @param context the {@code WebApplicationContext} to create a {@link MockMvc} 090 * instance from; never {@code null} 091 * @param configurer the {@code MockMvcConfigurer} to apply; never {@code null} 092 * @return the MockMvcWebClientBuilder to customize 093 */ 094 public static MockMvcWebClientBuilder webAppContextSetup(WebApplicationContext context, MockMvcConfigurer configurer) { 095 Assert.notNull(context, "WebApplicationContext must not be null"); 096 Assert.notNull(configurer, "MockMvcConfigurer must not be null"); 097 return new MockMvcWebClientBuilder(context, configurer); 098 } 099 100 /** 101 * Supply the {@code WebClient} that the client {@linkplain #build built} 102 * by this builder should delegate to when processing 103 * non-{@linkplain WebRequestMatcher matching} requests. 104 * @param webClient the {@code WebClient} to delegate to for requests 105 * that do not match; never {@code null} 106 * @return this builder for further customization 107 * @see #build() 108 */ 109 public MockMvcWebClientBuilder withDelegate(WebClient webClient) { 110 Assert.notNull(webClient, "WebClient must not be null"); 111 webClient.setWebConnection(createConnection(webClient)); 112 this.webClient = webClient; 113 return this; 114 } 115 116 /** 117 * Build the {@link WebClient} configured via this builder. 118 * <p>The returned client will use the configured {@link MockMvc} instance 119 * for processing any {@linkplain WebRequestMatcher matching} requests 120 * and a delegate {@code WebClient} for all other requests. 121 * <p>If a {@linkplain #withDelegate delegate} has been explicitly configured, 122 * it will be used; otherwise, a default {@code WebClient} will be configured 123 * as the delegate. 124 * @return the {@code WebClient} to use 125 * @see #withDelegate(WebClient) 126 */ 127 public WebClient build() { 128 return (this.webClient != null ? this.webClient : withDelegate(new WebClient()).build()); 129 } 130 131}