Specflow上下文注入

Specflow context injection

这里是关于 specflow 中上下文注入的问题。我的实体 class:

public class OrderInfo
{
    public string Status { get; set; }
    public string OrderName { get; set; }
}

在另一个 class 中,我正在使用此实体创建新订单:

[Binding]
public class OrderSteps
{
    private NgWebDriver driver;
    private OrderInfo orderInfo = new OrderInfo();

    public OrderSteps(NgWebDriver driver,OrderInfo orderInfo)
    {
        this.orderInfo = orderInfo;
        this.driver = driver;
    }

    [When(@"I am creating new order")]
    public void WhenIAmCreatingNewOrder(Table table)
    {
        var orderListPage = new OrdersListPage(driver);
        orderInfo = orderListPage.CreateNewOrder(table.CreateInstance<OrderInfo>());
    }
}

在这个 class 我的方法中 returns 一些数据存储在 'orderInfo' 对象中。一切正常,直到我需要在另一个 class 中使用该对象的数据。我正在尝试获取我的对象数据,但里面是空的....

    [Binding]
public class BuyerPortalSteps
{
    private NgWebDriver driver;
    private OrderInfo orderInfo;

    public BuyerPortalSteps(NgWebDriver driver, OrderInfo orderInfo)
    {
        this.driver = driver;
        this.orderInfo = orderInfo;
    }
}

所以问题是:如何使用第一个class

的数据填充的对象中的第二个class的数据

看来我找到了解决办法。我为我的 OrderInfo 创建了一个子子 [​​=21=]:

public class OrderInfoContext
{
    public OrderInfo OrderInfo { get; set; }
}

我的绑定有一些变化class:

public class OrderSteps
{
    private NgWebDriver driver;
    private List<FilterInfo> filterData = new List<FilterInfo>();
    private OrderInfoContext orderInfoContext;
    private OrderInfo orderInfo;

    public OrderSteps(NgWebDriver driver, OrderInfoContext orderInfoContext)
    {
        this.driver = driver;
        this.orderInfoContext = orderInfoContext;
    }

    [When(@"I am creating new order")]
    public void WhenIAmCreatingNewOrder(Table table)
    {
        var orderListPage = new OrdersListPage(driver);
        orderInfo = orderListPage.CreateNewOrder(table.CreateInstance<OrderInfo>());
        orderInfoContext.OrderInfo = orderInfo;
    }
}

现在我可以在我的另一个 class:

中使用存储的信息
    [Binding]
public class BuyerPortalSteps
{
    private NgWebDriver driver;
    private OrderInfoContext orderInfoContext;

    public BuyerPortalSteps(NgWebDriver driver, OrderInfoContext orderInfoContext)
    {
        this.driver = driver;
        this.orderInfoContext = orderInfoContext;
    }

    [Then(@"I am looking for order on buyer statistics grid")]
    public void ThenIAmLookingForOrderOnBuyerStatisticsGrid()
    {
        BuyerPortalDashboard buyerPortalDashboard = new BuyerPortalDashboard(driver);
        buyerPortalDashboard.CheckBuyerDashboardStatistic(orderInfoContext.OrderInfo);
    }
}

我认为原因是如果你想在 classes 之间共享数据你必须初始化这个数据一次并且永远不要尝试再次编辑它,因为它可以在途中的任何地方改变在您阅读之前....这只是我的假设

您可以使用 ScenarioContext 并传递它。这种方法的好处是您不需要向对象容器注册任何新内容。

要在 OrderSteps 中创建 "current order":

[Binding]
public class OrderSteps
{
    private readonly NgWebDriver driver;
    private readonly ScenarioContext scenario;

    private OrderInfo CurrentOrder
    {
        get => (OrderInfo)scenario["OrderInfo"];
        set => scenario["OrderInfo"] = value;
    }

    public OrderSteps(NgWebDriver driver, ScenarioContext scenario)
    {
        this.driver = driver;
        this.scenario = scenario;
    }

    [When(@"I am creating new order")]
    public void WhenIAmCreatingNewOrder(Table table)
    {
        var orderListPage = new OrdersListPage(driver);

        CurrentOrder = orderListPage.CreateNewOrder(table.CreateInstance<OrderInfo>());;
    }
}

然后在另一个 class:

中使用 OrderInfo 对象
[Binding]
public class BuyerPortalSteps
{
    private readonly NgWebDriver driver;
    private readonly ScenarioContext scenario;
    private OrderInfo CurrentOrder => (OrderInfo)scenario["OrderInfo"];

    public BuyerPortalSteps(NgWebDriver driver, ScenarioContext scenario)
    {
        this.driver = driver;
        this.scenario = scenario;
    }

    [Then(@"I am looking for order on buyer statistics grid")]
    public void ThenIAmLookingForOrderOnBuyerStatisticsGrid()
    {
        var buyerPortalDashboard = new BuyerPortalDashboard(driver);

        buyerPortalDashboard.CheckBuyerDashboardStatistic(CurrentOrder);
    }
}

我还在 ScenarioContext 上创建了扩展方法,这也很方便:

namespace YourProject.Tests
{
    public static class OrderScenarioContextExtensions
    {
        public static OrderInfo GetCurrentOrder(this ScenarioContext scenario)
        {
            return (OrderInfo)scenario["OrderInfo"];
        }

        public static void SetCurrentOrder(this ScenarioContext scenario, OrderInfo currentOrder)
        {
            scenario["OrderInfo"] = currentOrder;
        }
    }
}

然后你可以在任何有 ScenarioContext 对象的地方调用这些扩展方法:

var order = scenario.GetCurrentOrder();

var order = new OrderInfo();

scenario.SetCurrentOrder(order);

更多信息:Scenario context injection (SpecFlow docs)