简单案例
首先来看一个简单的案例
1 使用start.spring.io创建一个“web”项目。在“依赖项”对话框中搜索并添加“web”依赖项,如屏幕截图所示。点击“生成”按钮,下载zip,并将其解压缩到计算机上的文件夹中。
2 修改pom.xml
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <groupId>com.example</groupId> <artifactId>com.example</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> <java.version>11</java.version> <cucumber.version>6.8.1</cucumber.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-spring</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit-platform-engine</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> </dependencies> </project>
目录结构如下图
Hello.feature
代码语言:javascript
复制
Feature: Hello world Scenario: Calling a rest end point * the application says hello
HelloController.java
代码语言:javascript
复制
package com.example.BDDSpring; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Application { @RestController public static class HelloController { @RequestMapping("/") public String local() { return "Greetings from Local!"; } } }
HelloController.java
代码语言:javascript
复制
package com.example.BDDSpring; import io.cucumber.java.en.Given; import io.cucumber.junit.platform.engine.Cucumber; import io.cucumber.spring.CucumberContextConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import static org.hamcrest.CoreMatchers.equalTo; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Cucumber @CucumberContextConfiguration @SpringBootTest @AutoConfigureMockMvc public class CucumberTest { @Autowired private MockMvc mvc; @Given("the application says hello") public void getLocalHello() throws Exception { mvc.perform(get("/").accept(APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Greetings from Local!"))); } }
用JUnit运行HelloController.java,测试成功
二 一个正式的案例
1 使用start.spring.io创建一个“web”项目。在“依赖项”对话框中搜索并添加“web”依赖项,为了后面的契约文件,再加入“Config Client ”和“Contract Stub Runner依赖项。如屏幕截图所示。点击“生成”按钮,下载zip,并将其解压缩到计算机上的文件夹中。
2 pom.xml
代码语言:javascript
复制
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <groupId>com.example</groupId> <artifactId>com.example</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> <java.version>11</java.version> <cucumber.version>6.8.1</cucumber.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-spring</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit-platform-engine</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> </dependencies> </project>
3 目录结构如下
4 ATMService.feature
代码语言:javascript
复制
# language: zh-CN 功能:验证密码 作为银行储户 我想要在 ATM 上验证密码 以便我可以安全地进行操作 场景:查询余额 假如储户拥有一张卡号为"1111222233"的借记卡 并且密码为"123456" 并且储户借记卡账户余额为"100.00"元 当储户将卡插入ATM 并且储户选择查询余额 那么提示储户输入密码 并且输入密码"123456" 那么储户可以看到自己的余额"100.00"元 场景:查询余额密码验证不通过 假如储户拥有一张卡号为"1111222233"的借记卡 并且密码为"123456" 并且储户借记卡账户余额为"100.00"元 当储户将卡插入ATM 并且储户选择查询余额 那么提示储户输入密码 并且输入密码"456987" 那么储户可以看到密码错误的提示
5 先来看看测试文件
MyDemoApplicationTests.java
代码语言:javascript
复制
package com.example.ATMService; import io.cucumber.junit.platform.engine.Cucumber; import io.cucumber.spring.CucumberContextConfiguration; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @Cucumber @CucumberContextConfiguration @SpringBootTest class MyDemoApplicationTests { @Test void contextLoads() { } }
VerifyPINStepDefinitions.java
代码语言:javascript
复制
package com.example.ATMService; import com.example.ATMService.domain.model.Account; import com.example.ATMService.domain.model.DebitCard; import com.example.ATMService.performer.ATM; import com.example.ATMService.performer.Customer; import io.cucumber.java.zh_cn.假如; import io.cucumber.java.zh_cn.当; import io.cucumber.java.zh_cn.那么; import io.cucumber.junit.platform.engine.Cucumber; import static org.junit.Assert.assertEquals; import org.springframework.boot.test.context.SpringBootTest; @Cucumber @SpringBootTest public class VerifyPINStepDefinitions { private final Customer customer = new Customer(); private final ATM atm = new ATM(); @假如("储户拥有一张卡号为\"{int}\"的借记卡") public void 储户拥有一张卡号为_的借记卡(Integer cardIdInteger){ Long cardId = cardIdInteger.longValue(); this.customer.haveCard(new DebitCard(cardId)); } @假如("密码为\"{int}\"") public void 密码为(Integer PIN){ this.customer.setDebitCardPIN(PIN); } @假如("储户借记卡账户余额为\"{double}\"元") public void 储户借记卡账户余额为_元(Double balance){ this.customer.setCardAccount(new Account(balance)); } @当("储户将卡插入ATM") public void 储户将卡插入atm(){ this.customer.insertCardToATM(atm); } @当("储户选择查询余额") public void 储户选择查询余额(){ this.customer.queryBalanceOn(atm); } @那么("提示储户输入密码") public void 提示储户输入密码(){ assertEquals("Please input PIN:", this.atm.getScreenMessage()); } @那么("输入密码\"{int}\"") public void 输入密码(Integer pin){ this.customer.enterPIN(this.atm, pin); } @那么("储户可以看到自己的余额\"{double}\"元") public void 储户可以看到自己的余额_元(Double balance){ assertEquals(String.format("Your balance is: %,f", balance), this.atm.getScreenMessage()); } @那么("储户可以看到密码错误的提示") public void 储户可以看到密码错误的提示(){ assertEquals("your PIN is invalid.", this.atm.getScreenMessage()); } }
现在再来完成产品文件
com.example.ATMService目录下AtmServiveApplication.java
代码语言:javascript
复制
package com.example.ATMService; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class AtmServiveApplication { public static void main(String[] args) { SpringApplication.run(AtmServiveApplication.class, args); } }
com.example.ATMService.domain.model目录下Account.java
代码语言:javascript
复制
package com.example.ATMService.domain.model; public class Account { private final Double balance; public Account(Double balance) { this.balance = balance; } public double getBalance() { return balance; } }
com.example.ATMService.domain.model目录下DebitCard.java
代码语言:javascript
复制
package com.example.ATMService.domain.model; public class DebitCard { private Integer PIN= -1; private final Long cardId; private Account account; public DebitCard(Long cardId){ this.cardId = cardId; } public void setPIN(Integer pin){ this.PIN = pin.intValue(); } public void setAccount(Account account) { this.account = account; } public double getBalance() { return this.account.getBalance(); } public boolean verifyPIN(Integer pin) { return this.PIN.intValue()== pin; } public Long getCardID() { return this.cardId; } }
com.example.ATMService.domain.service目录下DebitCardService.java
代码语言:javascript
复制
package com.example.ATMService.domain.service; public class DebitCardService { public boolean verifyPIN(Long cardID, Integer pin){ return pin == 123456; } }
com.example.ATMService.performer目录下ATM.java
代码语言:javascript
复制
package com.example.ATMService.performer; import com.example.ATMService.domain.model.DebitCard; import com.example.ATMService.domain.service.DebitCardService; public class ATM { private DebitCard card; private String screenMessage; private boolean verifiedPIN = false; private DebitCardService debitCardService = new DebitCardService(); public void insertCard(DebitCard debitCard) { this.card = debitCard; } public void queryBalance() { if(this.verifiedPIN){ this.screenMessage = String.format("Your balance is: %f", this.card.getBalance()); }else { this.screenMessage = String.format("Please input PIN:"); } } public String getScreenMessage() { return this.screenMessage; } public void enterPlN(Integer pin) { this.verifiedPIN = this.debitCardService.verifyPIN(this.card.getCardID(), pin); if (!this.verifiedPIN) { this.screenMessage ="your PIN is invalid."; }else { this.queryBalance(); } } }
com.example.ATMService.performer目录下Customer.java
代码语言:javascript
复制
package com.example.ATMService.performer; import com.example.ATMService.domain.model.Account; import com.example.ATMService.domain.model.DebitCard; public class Customer { private DebitCard debitCard; public void haveCard(DebitCard debitCard) { this.debitCard = debitCard; } public void setDebitCardPIN(Integer pin){ this.debitCard.setPIN(pin); } public void setCardAccount(Account account) { this.debitCard.setAccount(account); } public void insertCardToATM(ATM atm){ atm.insertCard(this.debitCard); } public void queryBalanceOn(ATM atm) { atm.queryBalance(); } public void enterPIN(ATM atm, Integer pin) { atm.enterPlN(pin); } }
6用JUnit运行VerifyPINStepDefinitions.Java