【问题标题】:Specflow context injection规格上下文注入
【发布时间】:2020-07-19 22:33:04
【问题描述】:

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

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

在另一个类中,我正在使用这个实体来创建新订单:

[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>());
    }
}

在这个类中,我的方法返回一些存储在“orderInfo”对象中的数据。一切都很好,直到我需要在另一个类中使用该对象的数据。我正在尝试获取我的对象数据,但里面是空的......

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

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

所以问题是:如何从已经填充了第一类数据的对象中使用第二类的数据

【问题讨论】:

    标签: c# automation specflow


    【解决方案1】:

    似乎我找到了解决方案。我为我的 OrderInfo 创建了一个子类:

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

    我的 Binding 类也有一些变化:

    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;
        }
    }
    

    现在我可以在其他班级中使用存储的信息了:

        [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);
        }
    }
    

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

    【讨论】:

      【解决方案2】:

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

      在 OrderSteps 中创建“当前订单”:

      [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>());;
          }
      }
      

      然后在另一个类中使用 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)

      【讨论】:

        猜你喜欢
        • 2010-12-31
        • 2018-12-08
        • 1970-01-01
        • 2015-08-16
        • 1970-01-01
        • 1970-01-01
        • 2021-08-07
        • 2017-11-05
        • 1970-01-01
        相关资源
        最近更新 更多