å€ãã®ãã©ãããã©ãŒã ãšã¯ç°ãªããJavaã«ã¯æ¥ç¶ã¹ã¿ãã©ã€ãã©ãªãäžè¶³ããŠããŸãã ãã®äžçã«é·ãéäœãã§ãããªããããããWireMockãBetamaxããŸãã¯Spockã«ç²ŸéããŠããã¯ãã§ãã ãã¹ãã®å€ãã®éçºè
ã¯ãMockitoã䜿çšããŠãªããžã§ã¯ãã®åäœãããŒã«ã«h2ããŒã¿ããŒã¹ã䜿çšããDataJpaTestãCucumberãã¹ããèšè¿°ããŸãã ä»æ¥ã¯ããããã®ã¢ãããŒãã䜿çšããŠçºçããå¯èœæ§ã®ããããŸããŸãªåé¡ã«å¯ŸåŠããã®ã«åœ¹ç«ã€è»œéã®ä»£æ¿æ段ã«äŒããŸãã ç¹ã«ãanyStubã¯æ¬¡ã®åé¡ã解決ããããšããŸãã
- ãã¹ãç°å¢ã®æ§æãç°¡çŽ åãã
- ãã¹ãçšã®ããŒã¿åéãèªååãã
- ã¢ããªã±ãŒã·ã§ã³ã®ãã¹ããç¶ããä»ã®äœãã®ãã¹ããé¿ãã
anyStubãšã¯äœã§ããïŒ
AnyStubã¯é¢æ°åŒã³åºããã©ãããããã§ã«èšé²ãããŠããäžèŽããåŒã³åºããèŠã€ããããšããŸãã ããã«ããã次ã®2ã€ã®ããšãèµ·ãããŸãã
- äžèŽããåŒã³åºããããå ŽåãanyStubã¯ãã®åŒã³åºãã«é¢é£ä»ããããèšé²ãããçµæã埩å
ãããããè¿ããŸã
- äžèŽããåŒã³åºãããªããå€éšã·ã¹ãã ãžã®ã¢ã¯ã»ã¹ãèš±å¯ãããŠããå ŽåãanyStubã¯ãã®åŒã³åºããè¡ãããã®çµæãèšé²ããŠè¿ããŸã
ããã«äœ¿çšã§ããanyStubã¯ãhttpãªã¯ãšã¹ãã®ã¹ã¿ããšjavax.sqlããã®ããã€ãã®ã€ã³ã¿ãŒãã§ãŒã¹ãäœæããããã®Apache HttpClientããhttpã¯ã©ã€ã¢ã³ãã®ã©ãããŒãæäŸããŸãã ä»ã®æ¥ç¶çšã®ã¹ã¿ããäœæããããã®APIãæäŸãããŸãã
AnyStubã¯åçŽãªã¯ã©ã¹ã©ã€ãã©ãªã§ãããç°å¢ã®ç¹å¥ãªæ§æã¯å¿
èŠãããŸããã ãã®ã©ã€ãã©ãªã¯ãã¹ããªã³ã°ããŒãã¢ããªã±ãŒã·ã§ã³ã䜿çšããããšãç®çãšããŠããããã®ãã¹ã«åŸãããšã§æ倧éã®ã¡ãªãããåŸãããŸãã Springã®å€éšããã¬ãŒã³ãªJavaã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšã§ããŸãããééããªãè¿œå ã®äœæ¥ãå¿
èŠã«ãªããŸãã 以äžã®èª¬æã¯ãã¹ããªã³ã°ããŒãã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãã«çŠç¹ãåœãŠãŠããŸãã
çµ±åãã¹ããèŠãŠã¿ãŸãããã ããã¯ãã·ã¹ãã ããã¹ãããæããšããµã€ãã£ã³ã°ã§å
æ¬çãªæ¹æ³ã§ãã å®éãéæ³ã®æ³šéãæžããšããspring-bootãšJUnitã¯ã»ãšãã©ãã¹ãŠãè¡ããŸãã
@RunWith(SpringRunner.class) @SpringBootTest
çŸåšãçµ±åãã¹ãã¯éå°è©äŸ¡ãããŠãããéãããç¯å²ã§äœ¿çšãããŠãããäžéšã®éçºè
ã¯ããããé¿ããŠããŸãã ããã¯äž»ã«ããã¹ãã®æºåãšã¡ã³ããã³ã¹ã«æéããããããããŸãã¯ãã«ããµãŒããŒã§ç°å¢ãç¹å¥ã«æ§æããå¿
èŠãããããã§ãã
anyStubã䜿çšãããšãã¹ããªã³ã°ã³ã³ããã¹ããç¡å¹ã«ããå¿
èŠã¯ãããŸããã 代ããã«ãã³ã³ããã¹ããæ¬çªæ§æã«è¿ã¥ããããšã¯ç°¡åã§ç°¡åã§ãã
ãã®äŸã§ã¯ãPivoââtalã®ããã¥ã¢ã«ããanyStubãConsuming a RESTful Web Serviceã«æ¥ç¶ããæ¹æ³ã説æããŸãã
pom.xmlãä»ããŠã©ã€ãã©ãªãæ¥ç¶ãã
<dependency> <groupId>org.anystub</groupId> <artifactId>anystub</artifactId> <version>0.2.27</version> <scope>test</scope> </dependency>
次ã®ã¹ãããã¯ãã¹ããªã³ã°ã³ã³ããã¹ããå€æŽããããšã§ãã
package hello; import org.anystub.http.StubHttpClient; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class TestConfiguration { @Bean public RestTemplateBuilder builder() { RestTemplateCustomizer restTemplateCustomizer = new RestTemplateCustomizer() { @Override public void customize(RestTemplate restTemplate) { HttpClient real = HttpClientBuilder.create().build(); StubHttpClient stubHttpClient = new StubHttpClient(real); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(stubHttpClient); restTemplate.setRequestFactory(requestFactory); } }; return new RestTemplateBuilder(restTemplateCustomizer); } }
ãã®å€æŽã«ãããã¢ããªã±ãŒã·ã§ã³å
ã®ã³ã³ããŒãã³ãã®é¢ä¿ã¯å€æŽãããŸããããåäžã®ã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£
ã®ã¿ã眮ãæããããŸãã ããã«ããã Barbara Lisk Substitution Principleã«éãããŸãã ã¢ããªã±ãŒã·ã§ã³ã®èšèšãããã䟵害ããªãå Žåããã®çœ®æã¯æ©èœã䟵害ããŸããã
ãã¹ãŠæºåå®äºã§ãã ãã®ãããžã§ã¯ãã«ã¯ãã§ã«ãã¹ããå«ãŸããŠããŸãã
@RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTest { @Autowired private RestTemplate restTemplate; @Test public void contextLoads() { assertThat(restTemplate).isNotNull(); } }
ãã®ãã¹ãã¯ç©ºã§ããããã§ã«ã¢ããªã±ãŒã·ã§ã³ã³ã³ããã¹ããå®è¡ããŠããŸãã ãããã楜ãã¿ãå§ãŸããŸã ã äžã§è¿°ã¹ãããã«ããã¹ãã®ã¢ããªã±ãŒã·ã§ã³ã³ã³ããã¹ãã¯ãå€éšã·ã¹ãã ãžã®httpãªã¯ãšã¹ããå®è¡ãããCommandLineRunnerãäœæãããäœæ¥ã³ã³ããã¹ããšäžèŽããŸãã
@SpringBootApplication public class Application { private static final Logger log = LoggerFactory.getLogger(Application.class); public static void main(String args[]) { SpringApplication.run(Application.class); } @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); } @Bean public CommandLineRunner run(RestTemplate restTemplate) throws Exception { return args -> { Quote quote = restTemplate.getForObject( "https://gturnquist-quoters.cfapps.io/api/random", Quote.class); log.info(quote.toString()); }; } }
ããã¯ãã©ã€ãã©ãªã®åäœã瀺ãã®ã«ååã§ãã åããŠãã¹ããéå§ãããšãæ°ããcomplete/src/test/resources/anystub/stub.yml
ã
request0: exception: [] keys: [GET, HTTP/1.1, 'https://gturnquist-quoters.cfapps.io/api/random'] values: [HTTP/1.1, '200', OK, 'Content-Type: application/json;charset=UTF-8', 'Date: Thu, 25 Apr 2019 23:04:49 GMT', 'X-Vcap-Request-Id: 5ffce9f3-d972-4e95-6b5c-f88f9b0ae29b', 'Content-Length: 177', 'Connection: keep-alive', '{"type":"success","value":{"id":3,"quote":"Spring has come quite a ways in addressing developer enjoyment and ease of use since the last time I built an application using it."}}']
ã©ããã spring-bootã¯ããã¹ãæ§æããã¢ããªã±ãŒã·ã§ã³ã«RestTemplateBuilderãæ§ç¯ããŸããã ããã«ãããhttpã¯ã©ã€ã¢ã³ãã®ã¹ã¿ãå®è£
ãä»ããŠã¢ããªã±ãŒã·ã§ã³ãå®è¡ãããŸããã StubHttpClientã¯ãªã¯ãšã¹ããã€ã³ã¿ãŒã»ããããã¹ã¿ããã¡ã€ã«ãèŠã€ããããããªã¯ãšã¹ããå®è¡ããçµæããã¡ã€ã«ã«ä¿åãããã¡ã€ã«ããå埩ããçµæãè¿ããŸããã
ãã以éãã€ã³ã¿ãŒãããã«æ¥ç¶ããã«ãã®ãã¹ããå®è¡ã§ãããã®ãªã¯ãšã¹ãã¯æåããŸãã restTemplate.getForObject()
ã¯åãçµæãè¿ããŸãã å°æ¥ã®ãã¹ãã§ãã®äºå®ã«é Œãããšãã§ããŸãã
説æãããŠãããã¹ãŠã®å€æŽã¯GitHubã§èŠã€ããããšãã§ããŸãã
å®éããŸã åäžã®ãã¹ããäœæããŠããŸããã ãã¹ããäœæããåã«ãããŒã¿ããŒã¹ã§ã©ã®ããã«æ©èœããããèŠãŠã¿ãŸãããã
ãã®äŸã§ã¯ãPivoââtalããã¥ã¢ã«ã®SpringãšJDBCã䜿çšãããªã¬ãŒã·ã§ãã«ããŒã¿ãžã®ã¢ã¯ã»ã¹ã«çµ±åãã¹ããè¿œå ããŸã ã
ãã®å Žåã®ãã¹ãæ§æã¯æ¬¡ã®ããã«ãªããŸãã
package hello; import org.anystub.jdbc.StubDataSource; import org.h2.jdbcx.JdbcDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class TestConfiguration { @Bean public DataSource dataSource() { JdbcDataSource ds = new JdbcDataSource(); ds.setURL("jdbc:h2:./test"); return new StubDataSource(ds); } }
ããã§ã¯ãå€éšããŒã¿ããŒã¹ã«å¯ŸããŠéåžžã®ããŒã¿ãœãŒã¹ãäœæãããã¹ã¿ãå®è£
-StubDataSourceã¯ã©ã¹ã§ã©ãããããŸãã Spring-bootã¯ãããã³ã³ããã¹ãã«åã蟌ã¿ãŸãã ãŸãããã¹ãã§ã¹ããªã³ã°ã³ã³ããã¹ããå®è¡ããã«ã¯ãå°ãªããšã1ã€ã®ãã¹ããäœæããå¿
èŠããããŸãã
package hello; import org.anystub.AnyStubId; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.*; @RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTest { @Test @AnyStubId public void test() { } }
ããã空ã®ãã¹ãã§ã-ãã®å¯äžã®ã¿ã¹ã¯ã¯ã¢ããªã±ãŒã·ã§ã³ã³ã³ããã¹ããå®è¡ããããšã§ãã ããã§ã¯ãéåžžã«éèŠãªã¢ãããŒã·ã§ã³@AnystubId
ã衚瀺ãããŸããããŸã å«ãŸããŠããŸããã
æåã®å®è¡åŸããã¹ãŠã®ããŒã¿ããŒã¹åŒã³åºããå«ãæ°ããsrc/test/resources/anystub/stub.yml
ãsrc/test/resources/anystub/stub.yml
ã ããŒã¿ããŒã¹ã䜿çšãããšãæ¥ãèå°è£ã§ã©ã®ããã«æ©èœãããã«é©ãã§ãããã ãã¹ããæ°ãã«å®è¡ããŠããããŒã¿ããŒã¹ãžã®å®éã®ã¢ã¯ã»ã¹ã¯è¡ãããªãããšã«æ³šæããŠãã ããã test.mv.dbãåé€ãããšããã¹ããç¹°ãè¿ãå®è¡ããŠã衚瀺ãããŸããã å€æŽã®å®å
šãªã»ããã¯GitHubã§è¡šç€ºã§ããŸãã
ãŸãšãããšã anyStubã®å ŽåïŒ
- ãã¹ãç°å¢ãã«ã¹ã¿ãã€ãºããå¿
èŠã¯ãããŸãã
- ãã¹ãã¯å®éã®ããŒã¿ã§å®è¡ãããŸã
- ãã¹ãã®æåã®å®è¡ã¯ä»®å®ã蚌æãããã¹ãããŒã¿ãä¿åããŸãããã®åŸã®ãã¹ãã§ã¯ãã·ã¹ãã ãå£åããŠããªãããšã確èªããŸã
ããããçåããããŸããããŒã¿ããŒã¹ããŸã ååšããªãå Žåãã©ã®ããã«ãããã«ããŒããã®ããåŠå®çãªãã¹ããšäŸå€åŠçãã©ãããã®ãã ããã«æ»ããŸãããæåã«ãç°¡åãªãã¹ãã®äœæã«åãçµã¿ãŸãã
çŸåšãRESTful WebãµãŒãã¹ã®äœ¿çšãå®éšããŠããŸã ã ãã®ãããžã§ã¯ãã«ã¯ããã¹ãå¯èœãªã³ã³ããŒãã³ãã¯å«ãŸããŠããŸããã ã¢ãŒããã¯ãã£èšèšã®2ã€ã®å±€ãè¡šã2ã€ã®ã¯ã©ã¹ãäžã«äœæãããŸãã
package hello; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Component public class DataProvider { private final RestTemplate restTemplate; public DataProvider(RestTemplate restTemplate) { this.restTemplate = restTemplate; } Quote provideData() { return restTemplate.getForObject( "https://gturnquist-quoters.cfapps.io/api/random", Quote.class); } }
DataProviderã¯ãããŒã¿ãžã®ã¢ã¯ã»ã¹ãæäŸããŸã æ®çºæ§ å€éšã·ã¹ãã ã
package hello; import org.springframework.stereotype.Component; @Component public class DataProcessor { private final DataProvider dataProvider; public DataProcessor(DataProvider dataProvider) { this.dataProvider = dataProvider; } int processData() { return dataProvider.provideData().getValue().getQuote().length(); } }
DataProcessorã¯ãå€éšã·ã¹ãã ããã®ããŒã¿ãåŠçããŸãã
DataProcessor
ããã¹ãããDataProcessor
ã§ãã åŠçã¢ã«ãŽãªãºã ã®æ£ç¢ºæ§ããã¹ãããå°æ¥ã®å€æŽã«ããå£åããã·ã¹ãã ãä¿è·ããå¿
èŠããããŸãã
ãããã®ç®æšãéæããã«ã¯ãããŒã¿ã»ããã䜿çšããŠDataProviderã¢ãã¯ãªããžã§ã¯ããäœæãããã¹ãã§DataProcessorã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããšãæ€èšããŸãã å¥ã®æ¹æ³ãšããŠãDataProcessorãå解ããŠQuoteã¯ã©ã¹ã®åŠçã匷調衚瀺ããããšãã§ããŸãã 次ã«ããã®ãããªã¯ã©ã¹ã¯ãåäœãã¹ãã䜿çšããŠç°¡åã«ãã¹ãã§ããŸãïŒããã¯ãã¯ãªãŒã³ã³ãŒãã«é¢ããèæžã§æšå¥šãããæ¹æ³ã§ãïŒã ã³ãŒãã®å€æŽãšãã¹ãããŒã¿ã®çºæãé¿ãããã¹ããäœæããŠã¿ãŸãããã
@RunWith(SpringRunner.class) @SpringBootTest public class DataProcessorTest { @Autowired private DataProcessor dataProcessor; @Test @AnyStubId(filename = "stub") public void processDataTest() { assertEquals(131, dataProcessor.processData()); } }
@AnystubIdã¢ãããŒã·ã§ã³ã«ã€ããŠèª¬æããŸãã ãã®æ³šéã¯ããã¹ãã§ã¹ã¿ããã¡ã€ã«ã管çããã³å¶åŸ¡ããã®ã«åœ¹ç«ã¡ãŸãã ãã¹ãã¯ã©ã¹ãŸãã¯ãã®ã¡ãœããã§äœ¿çšã§ããŸãã ãã®æ³šéã¯ã察å¿ããé åã«åå¥ã®ã¹ã¿ããã¡ã€ã«ãèšå®ããŸãã ããããã®é åãã¯ã©ã¹ããã³ã¡ãœããã¬ãã«ã®ã¢ãããŒã·ã§ã³ã§åæã«ã«ããŒãããŠããå Žåãã¡ãœããã¢ãããŒã·ã§ã³ãåªå
ãããŸãã ãã®æ³šéã«ã¯ãã¹ã¿ããã¡ã€ã«ã®ååãå®çŸ©ããfilenameãã©ã¡ãŒã¿ãŒããããŸãã çç¥ããå Žåãæ¡åŒµåã.ymlããèªåçã«è¿œå ãããŸãã ãã®ãã¹ããå®è¡ããŠããæ°ãããã¡ã€ã«ã¯èŠã€ãããŸããã src/test/resources/anystub/stub.yml
ã¯ãã§ã«ä»¥åã«äœæãããŠããããã®ãã¹ãã¯ãããåå©çšããŸãã ã¯ãšãªã®çµæãåæããããšã«ããããã®ã¹ã¿ããã131çªãååŸããŸããã
@Test @AnyStubId public void processDataTest2() { assertEquals(131, dataProcessor.processData()); Base base = getStub(); assertEquals(1, base.times("GET")); assertTrue(base.history().findFirst().get().matchEx_to(null, null, ".*gturnquist-quoters.cfapps.io.*")); }
ãã®ãã¹ãã§ã¯ã@ AnyStubIdã¢ãããŒã·ã§ã³ãfilenameãã©ã¡ãŒã¿ãŒãªãã§è¡šç€ºãããŸãã ãã®å Žåã src/test/resources/anystubprocessDataTest2.yml
ãŸãã ãã¡ã€ã«åã¯ãé¢æ°ã®ååïŒã¯ã©ã¹ïŒ+ ".yml"ããäœæãããŸãã anyStubããã®ãã¹ãçšã®æ°ãããã¡ã€ã«ãäœæããããå®éã®ã·ã¹ãã ã³ãŒã«ãè¡ãå¿
èŠããããŸãã ãããŠãæ°ããèŠç©ããã®ââé·ããåãã§ããããšã¯å¹žéã§ãã æåŸã®2ã€ã®ãã§ãã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ã®åäœããã¹ãããæ¹æ³ã瀺ããŠããŸãã ãã©ã¡ãŒã¿ãŸãã¯ãã©ã¡ãŒã¿ã®äžéšã«ãã£ãŠã¯ãšãªãéžæããã¯ãšãªã®æ°ãã«ãŠã³ãããŸãã ããã¥ã¡ã³ãã«ã¯ãæéãšäžèŽé¢æ°ã®ããªãšãŒã·ã§ã³ãããã€ããããŸã ã
@Test @AnyStubId(requestMode = RequestMode.rmTrack) public void processDataTest3() { assertEquals(79, dataProcessor.processData()); assertEquals(79, dataProcessor.processData()); assertEquals(168, dataProcessor.processData()); assertEquals(79, dataProcessor.processData()); Base base = getStub(); assertEquals(4, base.times("GET")); }
ãã®ãã¹ãã§ã¯ãæ°ããrequestModeãã©ã¡ãŒã¿ãŒãšãšãã«@AnyStubIdã衚瀺ãããŸãã ã¹ã¿ããã¡ã€ã«ã®æš©éã管çã§ããŸãã å¶åŸ¡ãã2ã€ã®åŽé¢ããããŸãïŒãã¡ã€ã«ã«ããæ€çŽ¢ãšå€éšã·ã¹ãã ãåŒã³åºãèš±å¯ã
RequestMode.rmTrack
ã¯ã次ã®ã«ãŒã«ãèšå®ããŸãïŒãã¡ã€ã«ãäœæãããã°ããã®å Žåããã¹ãŠã®èŠæ±ã¯å€éšã·ã¹ãã ã«éä¿¡ããããã¡ã€ã«ã«åäžã®èŠæ±ããããã©ããã«é¢ä¿ãªããåçãšãšãã«ãã¡ã€ã«ã«æžã蟌ãŸããŸãïŒãã¡ã€ã«å
ã®éè€ã¯èš±å¯ãããŸãïŒã ãã¹ããå®è¡ããåã«ã¹ã¿ããã¡ã€ã«ãååšããå Žåãå€éšã·ã¹ãã ãžã®ãªã¯ãšã¹ãã¯çŠæ¢ãããŠããŸãã åŒã³åºãã¯ãŸã£ããåãé åºã§è¡ãããŸãã 次ã®èŠæ±ããã¡ã€ã«å
ã®èŠæ±ãšäžèŽããªãå ŽåãäŸå€ãã¹ããŒãããŸãã
RequestMode.rmNew
ãã®ã¢ãŒãã¯ããã©ã«ãã§ã¢ã¯ãã£ãã«ãªã£ãŠããŸãã åèŠæ±ã¯ã¹ã¿ããã¡ã€ã«ã§æ€çŽ¢ãããŸãã äžèŽããèŠæ±ãèŠã€ãã£ãå Žå-察å¿ããçµæããã¡ã€ã«ãã埩å
ãããå€éšã·ã¹ãã ãžã®èŠæ±ã¯å»¶æãããŸãã èŠæ±ãèŠã€ãããªãå Žåãå€éšã·ã¹ãã ãèŠæ±ãããçµæããã¡ã€ã«ã«ä¿åãããŸãã ãã¡ã€ã«å
ã®éè€ãããªã¯ãšã¹ã-çºçããŸããã
RequestMode.rmNone
åãªã¯ãšã¹ãã¯ã¹ã¿ããã¡ã€ã«ã§æ€çŽ¢ãããŸãã äžèŽããã¯ãšãªãèŠã€ãã£ãå Žåããã®çµæã¯ãã¡ã€ã«ãã埩å
ãããŸãã ãã¹ãããã¡ã€ã«ã«ãªãèŠæ±ãçæãããšãäŸå€ãã¹ããŒãããŸãã
RequestMode.rmAll
ã¯ãæåã®èŠæ±ã®åã«ãã¹ã¿ããã¡ã€ã«ãæ¶å»ãããŸãã ãã¹ãŠã®èŠæ±ã¯ãã¡ã€ã«ã«æžã蟌ãŸããŸãïŒãã¡ã€ã«å
ã®éè€ã¯èš±å¯ãããŸãïŒã æ¥ç¶ã®åäœãç£èŠããå Žåã¯ããã®ã¢ãŒãã䜿çšã§ããŸãã
RequestMode.rmPassThrough
ãã¹ãŠã®èŠæ±ã¯ãå®è£
ã¹ã¿ãããã€ãã¹ããŠãå€éšã·ã¹ãã ã«çŽæ¥éä¿¡ãããŸãã
ãããã®å€æŽã¯GitHubã§å
¥æã§ããŸãã
ä»ã«äœïŒ
anyStubãå¿çãä¿åããæ¹æ³ãèŠãŸããã å€éšã·ã¹ãã ãžã®ã¢ã¯ã»ã¹æã«äŸå€ãã¹ããŒãããå ŽåãanyStubã¯ãããä¿åããåŸç¶ã®ãªã¯ãšã¹ãã§ãããåçŸããŸãã
å€ãã®å ŽåãäŸå€ã¯ãããã¬ãã«ã®ã¯ã©ã¹ã«ãã£ãŠã¹ããŒãããŸãããæ¥ç¶ã¯ã©ã¹ã¯æå¹ãªå¿çãååŸããŸãïŒãããããšã©ãŒã³ãŒãã§ïŒã ãã®å ŽåãanyStubã¯ãšã©ãŒã³ãŒãã䜿çšããŠçããåçŸããäžäœã¯ã©ã¹ããã¹ãã®äŸå€ãã¹ããŒããŸãã
ãªããžããªã«ã¹ã¿ããã¡ã€ã«ãè¿œå ããŸãã
ã¹ã¿ããã¡ã€ã«ãåé€ããŠäžæžãããããšãæããªãã§ãã ããã
ã¹ã¿ããã¡ã€ã«ãè³¢ã管çããŸãã 1ã€ã®ãã¡ã€ã«ãè€æ°ã®ãã¹ãã§åå©çšããããåãã¹ãã«åå¥ã®ãã¡ã€ã«ãæäŸã§ããŸãã å¿
èŠã«å¿ããŠãã®æ©äŒãå©çšããŠãã ããã ãã ããéåžžãç°ãªãã¢ã¯ã»ã¹ã¢ãŒãã§åäžã®ãã¡ã€ã«ã䜿çšããããšã¯ãå§ãã§ããŸããã
ãããã¯ãã¹ãŠanyStubã®äž»ãªæ©èœã§ãã