黄瓜-jvm的自定义数据表变换器

时间:2015-02-05 08:06:48

标签: java cucumber cucumber-jvm

我想在黄瓜中创建自定义数据表变换器。这就是我的功能:

Given board
| o | _ | _ |
| o | _ | _ |
| o | _ | _ |

我想将它放入自定义对象中。让我们说它看起来像这样:

class Board {

    private List<List<String>> board;

    public Board(List<List<String>> board) {
        this.board = board;
    }

}

我的步骤定义应如下所示:

@Given("^board$")
public void board(Board board) throws Throwable {
    // todo
}

步骤定义适用于DataTable类和List<List<String>>

@Given("^board$")
public void board(DataTable board) throws Throwable {
    // this works fine
}

这也很好用

@Given("^board$")
public void board(List<List<String>> board) throws Throwable {
    // this also works fine
}

我试图在互联网上找到解决方案但没有任何成功。我也尝试创建Transformer但是,正如我所看到的,它仅适用于字符串(我想在输入中使用Datatable或List&gt;):

class BoardTransformer extends Transformer<Board> {

    @Override
    public Board transform(String value) {
        // TODO Auto-generated method stub
        return null;
    }

}

4 个答案:

答案 0 :(得分:2)

在黄瓜3.x中,您可以使用TypeRegistryConfigurer来通知Cucumber应该如何从Board创建DataTable对象。因为要将整个表转换为单个对象,所以必须使用TableTransformer而不是TableCellTransformerTableEntryTransformerTableRowTransformer

您可以将TypeRegistryConfigurer放在胶水路径上的任何地方。

package io.cucumber.java.test;

import io.cucumber.core.api.TypeRegistryConfigurer;
import io.cucumber.core.api.TypeRegistry;
import io.cucumber.datatable.DataTableType;
import io.cucumber.datatable.TableTransformer;

import java.util.List;
import java.util.Locale;

import static java.util.Locale.ENGLISH;

public class TypeRegistryConfiguration implements TypeRegistryConfigurer {

    @Override
    public Locale locale() {
        return ENGLISH;
    }


    @Override
    public void configureTypeRegistry(TypeRegistry typeRegistry) {
        typeRegistry.defineDataTableType(new DataTableType(
            Board.class,
            (TableTransformer<Board>) table -> new Board(table.cells())));

    }

    static class Board {

        private final List<List<String>> board;

        private Board(List<List<String>> board) {
            this.board = board;
        }
    }
}

答案 1 :(得分:1)

在旧版本的黄瓜中,按照您所说的1.2.2,您必须请求对象列表,因为数据表的每一行(从功能文件的角度来看)都被视为不同的对象,例如

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
    <cache-path name="image" path="."/>
    </paths>

从v3开始,许多黄瓜已更改了数据表,例如从XStream切换到Jackson

但如先前建议,请尽可能升级您的黄瓜版本

答案 2 :(得分:0)

如果你可以选择

@Given("^board$")
public void board(List<List<String>> board) throws Throwable {
...

为什么不在

之后立即创建Board对象
Board board2 = new Board(board);

看起来你不需要变压器。

答案 3 :(得分:0)

假设目标是将“讨厌的参数转换内容”与“实际测试代码”分开,以便我可以在测试代码中使用漂亮的对象,那么我想出的最好的方法就是使用Jackson ObjectMapper(或其他一些支持Map to Object的反序列化库)的版本。

例如:

private ObjectMapper objectMapper = new ObjectMapper();

@When("I do some thing with input dataTable")
public void i_do_some_thing_with_input_dataTable(DataTable dataTable) {
    List<Map<String,String>> values = dataTable.asMaps(String.class, String.class);
    List<MyObject> inputs = values.stream().map(i -> objectMapper.convertValue(i,MyObject.class)).collect(Collectors.toList());

    inputs.forEach(i-> {
        //Do things with the input.
    });
}

您可以/当然应该将此转换包装在一些不错的服务类中,然后将其插入/实例化测试。

此代码假定以下内容:

  • 您正在使用带有标题的数据表
  • 您在MyObject中具有与表格标题对应的名称的字段
  • MyObject对于每个字段都有适当的getter / setter。
相关问题