在SpecFlow中,我应该为我正在测试的对象使用类字段还是场景上下文?

本文关键字:字段 上下文 对象 SpecFlow 我应该 测试 | 更新日期: 2023-09-27 18:11:17

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

我发现选项1要容易得多,因为我不需要一直获取和设置场景上下文。但是我已经学会了使用场景上下文。

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

在SpecFlow中,我应该为我正在测试的对象使用类字段还是场景上下文?

在我看来,您列出的两个选项都不是最佳解决方案。正如Andreas在另一个答案中指出的那样,最好的选择是使用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();
    }
}
在这样一个简单的示例中,

的好处可能并不明显,但根据我的经验,从长远来看,这会使您的生活简单得多。

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