我们的应用程序中有一些API无法从本地开发者机器访问,因为受到防火墙的限制。
我想使用mockServer来模拟其中一些API,以便我们可以在本地开发。
当运行测试时,可以使用Maven构建阶段process-test-classes
和verify
分别启动和停止mockServer。
如何在使用mvn spring-boot:run
启动应用程序时运行mockServer?
我们的应用程序中有一些API无法从本地开发者机器访问,因为受到防火墙的限制。
我想使用mockServer来模拟其中一些API,以便我们可以在本地开发。
当运行测试时,可以使用Maven构建阶段process-test-classes
和verify
分别启动和停止mockServer。
如何在使用mvn spring-boot:run
启动应用程序时运行mockServer?
可以在Spring Boot中覆盖bean。 因此,您可以根据需要使用您的bean并切换为模拟值。 下面的示例是覆盖服务并使用模拟值,但您也可以使用接口。
创建服务
@Service
public class ServiceReal {
@Autowired(required = false) // must be required=false. May be disabled by using mock configuration
private JdbcTemplate jdbcTemplate;
public String getInfo() {
return jdbcTemplate...// get a real value from database
}
}
@Service
@Primary
@Profile("mocklocal")
public class ServiceMock extend ServiceReal {
@Override
public String getInfo() {
return "Mocked value"
}
}
配置Bean以后在属性中选择其中之一
@Profile("mocklocal")
@PropertySource("classpath:application-mocklocal.properties")
@Configuration
public class ConfigMock {
private static final String PROP_VALUE_TRUE = "true";
private static final boolean PROP_FALSE_DEFAULT_MISSING = false;
private static final String PROP_SERVICE_REAL = "mocklocal.service.real";
private static final String PROP_SERVICE2_REAL = "mocklocal.service2.real";
@Bean
@ConditionalOnProperty( value = PROP_SERVICE_REAL, havingValue = PROP_VALUE_TRUE, matchIfMissing = PROP_FALSE_DEFAULT_MISSING)
public ServiceReal serviceReal(){
return new ServiceMock();
}
@Bean
@ConditionalOnProperty( value = PROP_SERVICE2_REAL, havingValue = PROP_VALUE_TRUE, matchIfMissing = PROP_FALSE_DEFAULT_MISSING)
public Service2Real service2Real(){
return new Service2Mock();
}
}
配置你的应用程序-mocklocal.properties以使用模拟
# using ConfigMock
spring.profiles.active=mocklocal
# settig spring to override service and use mock
spring.main.allow-bean-definition-overriding=true
# disable some configuration not required in mocks. you can adjust for amqp, database or other configuration
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.autoconfigure.exclude[1]=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
spring.autoconfigure.exclude[2]=org.springframework.boot.autoconfigure.orm.jpa.DataSourceTransactionManagerAutoConfiguration
# enable your service to use mocks not real services
mocklocal.service.real=true
mocklocal.service2.real=true
如果你使用 --spring.profiles.active=mocklocal 启动你的应用程序,你将得到模拟值
你也可以在测试中使用它
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
@SpringBootTest
@TestPropertySource(locations = "classpath:application-mocklocal.properties")
public class RunIntegrationTests {
@Autowired
private MockMvc mockMvc;
@Test
public void run() throws Exception{
...
}
}
<plugin>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-maven-plugin</artifactId>
<version>3.10.8</version>
<configuration>
<serverPort>1080</serverPort>
<proxyPort>1090</proxyPort>
<logLevel>DEBUG</logLevel>
<initializationClass>org.mockserver.maven.ExampleInitializationClass</initializationClass>
</configuration>
<executions>
<execution>
<id>process-test-classes</id>
<phase>process-test-classes</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
这将在process-test-classes
(即test
阶段之前)启动模拟服务器,并在validate
(即post-
integration-test
阶段之后)停止。
(link1, link2)
如何在使用mvn spring-boot:run启动应用程序时运行它?
要使用mvn spring-boot:run
运行它:
mvn mockserver:start spring-boot:run
!(将其打包到脚本/IDE启动中..)(推荐)mvn com.example:custom-plugin:run
).
我曾经为我的团队创建了一个MockServer,目的与这里相似(幸运的是,也有一个简短的演示可用)。您可以独立设置此服务器(例如在本地主机上),并将请求(url和负载)与所需的响应json添加到该服务器中。
您需要在项目内进行一次更改,即在开发/测试期间将所有API请求路由到此Mockserver,这可以通过更改您将使用的所有API的基本URL并设置具有适当JSON请求和响应的Mockserver来完成。它可以像这样简单地完成:
public class BaseUrlLoader {
public static String NEWSRIVER_BASE_URL;
public static String FACEBOOK_BASE_URL;
public static String TWITTER_BASE_URL;
private static final String MOCKSERVER_BASE_URL = "mocksrvr.herokuapp.com/TEAM-SECRET-KEY";
public static void load(){
Properties properties= new Properties();
String activeProfile;
try{
properties.load(ClassLoader.getSystemResourceAsStream("application.properties"));
} catch (IOException e) {
System.out.println("Not able to load the application.properties file");
return;
}
activeProfile = properties.getProperty("spring.profiles.active");
System.out.println("Using "+activeProfile);
if(activeProfile.equals("Test")){
NEWSRIVER_BASE_URL=MOCKSERVER_BASE_URL;
FACEBOOK_BASE_URL= MOCKSERVER_BASE_URL;
TWITTER_BASE_URL= MOCKSERVER_BASE_URL;
}else{
NEWSRIVER_BASE_URL="api.newsriver.io";
FACEBOOK_BASE_URL="api.facebook.com";
TWITTER_BASE_URL="api.twitter.com";
}
System.out.println(NEWSRIVER_BASE_URL);
}
}
// Example- Use APIs as
public class NewsFetch {
...
public NewsFetch(){ BaseUrlLoader.load(); }
private URI buildURL(APIQuery apiQuery) throws URISyntaxException {
String mainURL = BaseUrlLoader.NEWSRIVER_BASE_URL+"v2/search";
URIBuilder url = new URIBuilder(mainURL);
url.addParameter("query", apiQuery.getLuceneQuery());
url.addParameter("soryBy", apiQuery.getSortBy());
url.addParameter("sortOrder", apiQuery.getSortOrder());
url.addParameter("limit", apiQuery.getLimit());
return url.build();
}
public HttpResponse <String> fetch(APIQuery apiQuery) throws URISyntaxException, IOException, InterruptedException {
URI uri = buildURL(apiQuery);
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("Authorization", KEY)
.uri(uri)
.build();
...
}
}
// and add the request like http://mocksrvr.herokuapp.com/TEAM-SECRET-KEY/v2/search/... to the Mockserver with the response you want.
baseurl将根据当前活动配置文件而更改。这个模拟服务器很简单,甚至可以与Slackbot集成。更多信息请参阅自述文件。项目中可能会有许多错误,欢迎贡献。