在SpecFlow中,我应该为我正在测试的对象使用类字段还是ScenarioContext?

时间:2016-10-03 21:19:44

标签: c# specflow

我正在使用SpecFlow测试一个类MortgageCalculator。我发现我有两种方法来设置我的步骤文件,一种是我有一个类级别MortgageCalculator,另一种是我使用ScenarioContext(见下文)。哪个更好?

我发现选项1更容易,因为我不必继续获取和设置ScenarioContext。但是我被教会使用ScenarioContext。

选项1:

[Binding]
public sealed class MortgageCalculatorSteps
{
    private MortgageCalculator calculator;

    [Given(@"I have a MortgageCalculator")]
    public void GivenIHaveAMortgageCalculator()
    {
        calculator = new MortgageCalculator();
    }

    [Then(@"I can do something with the calculator")]
    public void ThenICanDoSomethingWithTheCalculator()
    {
        calculator.DoSomething();
    }
}

选项2:

[Binding]
public sealed class MortgageCalculatorSteps
{
    [Given(@"I have a MortgageCalculator")]
    public void GivenIHaveAMortgageCalculator()
    {
        var calculator = new MortgageCalculator();
        ScenarioContext.Current.Set(calculator);
    }

    [Then(@"I can do something with the calculator")]
    public void ThenICanDoSomethingWithTheCalculator()
    {
        var calculator = ScenarioContext.Current.Get<MortgageCalcualtor>();
        calculator.DoSomething();
    }
}

2 个答案:

答案 0 :(得分:2)

SpecFlow有一个名为Context Injection的概念 它是在场景的测试运行期间存储状态的首选方式 请查看此处的文档:http://www.specflow.org/documentation/Context-Injection/

答案 1 :(得分:2)

在我看来,您所概述的选项都不是最佳解决方案。正如安德烈亚斯在另一个答案中指出的那样,最好的选择是使用ContextInjection。为什么呢?

  • 在并行运行测试时工作,使用ScenarioContext.Current不会
  • 允许在包含步骤的不同类之间共享数据,这反过来允许您以任何方式组织步骤,并避免使用包含许多步骤方法的非常大的类
  • 允许您的数据加强类型
  • 允许您的数据收集在适当的内聚类中,每个类都保持单一责任原则

我们倾向于将这些类称为上下文,所以我的选择就是这样做,可能是:

[Binding]
public sealed class MortgageCalculatorSteps
{
    private MortgageCalculatorContext calculatorContext;

    public MortgageCalculatorSteps(MortgageCalculatorContext calculatorContext)
    {
        this.calculatorContext=calculatorContext;
    }

    [Given(@"I have a MortgageCalculator")]
    public void GivenIHaveAMortgageCalculator()
    {
        calculatorContext.Calculator = new MortgageCalculator();
        // or you could do something like: calculator.InitialiseCalculator()
    }

    [Then(@"I can do something with the calculator")]
    public void ThenICanDoSomethingWithTheCalculator()
    {
        calculatorContext.Calculator.DoSomething();
    }
}

在这样一个简单的例子中,好处可能并不明显,但根据我的经验,从长远来看,这会让你的生活变得更加简单。