如何在 Scenario 对象中为 属性 设置默认值(未调用构造函数!)

How to set default value for property in a Scenario object (constructor not called!)

考虑以下几点:

@Given("^this stuff:$")
public void this_stuff(List<ScenarioStuff> stuffList) throws Throwable {
    stuffList.get(0).isHappy();
}

和特征:

Given this stuff:
  |Name|
  |Miguel|

最后,场景对象:

ScenarioStuff{
private String name;
private boolean happy;
(getters and setters for name and happy, inlcuding:)
public boolean isHappy(){
    return happy;
    }

这是我的发现:

问题:

如果未在功能 table 中作为参数提供,我如何默认 happy=true

Cucumber 使用 XStream to convert step definition arguments to Java objects, so to answer this we have to dig in XStream 的方法来做到这一点。

this answer to an XStream question 所述,一种选择是使用 readResolve 方法(如果可用,XStream 显然会使用它来设置对象。

在我的特殊情况下,将 happy 变量从 boolean 更改为 Boolean 后,我最终得到了如下实现:

ScenarioStuff{
private String Name;
private Boolean happy;

private Object readResolve() {
        if(happy == null){
            happy = true;
        }
        return this;
  }
}

我还读到可以为 marshal/unmarshal 对象实现一个转换器,但我没有探索这个选项,因为 1) 它看起来不那么简单,并且 2) 我没有立即看到一个人会怎么做在黄瓜设置中注册这个新转换器。

更新 我添加了布尔值并让它们也起作用。

Scenario: An international coffee shop must handle currencies
Given the price list for an international coffee shop
  | product | currency | price | happy |
  | coffee  | EUR      | 1     | true  |
  | donut   | SEK      | 18    | false |
When I buy "1" "coffee" and "1" "donut"
Then I should pay "1" EUR be "happy" and "18" SEK be "unhappy"

步骤定义文件

public class datatable_steps {
    private HashMap<String, Price> intPriceList = new HashMap<String, Price>();
    private int sekSum;
    private int euroSum;

@Given("^the price list for an international coffee shop$")
public void the_price_list_for_an_international_coffee_shop(List<Price> prices) {

    int numPrices = prices.size();
    System.out.println("numPrices = " + numPrices);
    for(Price price : prices) {
        String key = price.getProduct();
        intPriceList.put(key,  price);
    }
}

@When("^I buy \"(\d+)\" \"(.*)\" and \"(\d+)\" \"(.*)\"$")
public void i_order_coffee_and_donut(int numberOfFirstItems, String firstItem,
                                     int numberOfSecondItems, String secondItem) throws Throwable {
    Price firstPrice = intPriceList.get(firstItem);
    calculate(numberOfFirstItems, firstPrice);
    Price secondPrice = intPriceList.get(secondItem);
    calculate(numberOfSecondItems, secondPrice);
}

private void calculate(int numberOfItems, Price price) {
    if (price.getCurrency().equals("SEK")) {
        sekSum += numberOfItems * price.getPrice();
        return;
    }
    if (price.getCurrency().equals("EUR")) {
        euroSum += numberOfItems * price.getPrice();
        return;
    }
    throw new IllegalArgumentException("The currency is unknown");
}

@Then("^I should pay \"(\d+)\" EUR be \"(.*)\" and \"(\d+)\" SEK be \"(.*)\"$")
public void should_I_pay_EUR_and_SEK(int expectedEuroSum, String eurHappy, int expectedSekSum, String sekHappy) throws Throwable {
    boolean eurHappyBool = false;
    boolean sekHappyBool = false;

    Assert.assertEquals(expectedEuroSum, euroSum);
    Assert.assertEquals(expectedSekSum,sekSum);

    if (eurHappy.equalsIgnoreCase("happy")) {
        eurHappyBool = true;
    }

    if (sekHappy.equalsIgnoreCase("happy")) {
        sekHappyBool = true;
    }

    Assert.assertEquals(eurHappyBool, intPriceList.get("coffee").isHappy());
    Assert.assertEquals(sekHappyBool, intPriceList.get("donut").isHappy());
}

}

Class 价格是这样的:

package runsupport;

public class Price {
    private String product;
    private String currency;
    private Integer price;
    private boolean happy;

    public Price(String product, Integer price, String currency){
        this.product = product;
        this.price = price;
        this.currency = currency;
    }

    public String getProduct() {
        return product;
    }

    public Integer getPrice() {
        return price;
    }

    public String getCurrency() {
        return currency;
    }

    public boolean isHappy() {
        return happy;
    }
}