简单案例
首先来看一个简单的案例
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