【问题标题】:How can I resolve an Object Reference error when calling Steps from my Step Definitions从我的步骤定义中调用步骤时如何解决对象引用错误
【发布时间】:2014-11-20 15:18:42
【问题描述】:

我想从我的一些步骤定义中调用 specflow 中的一些步骤。

问题是Given("I run a useful step"); 行不起作用。我得到了错误:

An object reference is required for the non-static field, method, or property `TechTalk.SpecFlow.Steps.Given(string)`.

但我正在按照维基上所说的去做。

这是我的设置:

[Binding]
public class Utility_Subtests:Steps
{
    [Given(@"I run a useful step")]
    public void IRunAUsefulStep()
    {
        //Some useful things
    }

    [When(@"I want to use a useful step")]
    public void IWantToUseAUsefulStep()
    {
        Given("I run a useful step");
    }
}

我不明白为什么这不起作用,因为它与示例中显示的几乎完全相同。

更新:

我通过删除我的一种方法中的“静态”解决了这个问题。傻我。

更新 2:更多信息

所以基本上在每个功能之前我想运行将登录到我们的交易系统并删除公司的代码,然后恢复它。我已经有了执行此操作的“步骤”,所以我只想在 BeforeFeature 方法中调用这些步骤。

我可以调用这些方法...但是我不能使用:string attribute = ScenarioContext.Current.CurrentScenarioBlock.ToString();,因为它不在场景上下文中,因为它在功能之前运行它是有意义的。

这是我的典型测试步骤之一:

[When(@"I ICE to the test account: ""(.*)""")]
public static void Subtest_IICEToTestAccount(string iceAccount)
{
    try
    {
        OpenVMSDriver.SendShellCommand("ICE SET " + iceAccount);
    }
    catch (Exception ex) { TestDriver.CatchNTrash(ex); }
    string attribute = ScenarioContext.Current.CurrentScenarioBlock.ToString();
    string attrValue = Utility.GetAttributeValue(attribute);
    TestDriver.ResultsLog.LogSubTest(attribute + " " + attrValue.Replace("(.*)",iceAccount));
}

它的作用是向 VMS 发送一个命令,并给我一个发生的日志。为了获得一些不错的细节,我捕获了当前场景块,然后读取属性的值并将其写入日志。

问题是如果我像这样调用这个方法:Subtest_IICEToTestAccount("Faster");

我将无法读取它们会引发异常的当前属性。

所以我想使用When("I ICE to the test account: FASTER");,但我得到了标题中的错误。也许这不是最好的方法,我应该只编写一个方法来处理删除和恢复公司的所有步骤。

【问题讨论】:

  • 减号评论有什么原因吗?
  • Given 是什么?是属性还是方法?
  • 它是 SpecFlow 中的一种方法,但据我所知,它是一种抽象方法。我将关闭 github 上的示例:github.com/techtalk/SpecFlow/wiki/…
  • 嗯。为我编译,使用最新的 SpecFlow 包。
  • 哦,我不觉得很傻...我的一种方法中有“静态”...我删除了它,现在它可以编译了。

标签: c# specflow


【解决方案1】:

你应该把它改成

[Binding]
public class Utility_Subtests:Steps
{

    [Given(@"I run a useful step")]
    public void IRunAUsefulStep()
    {
        //Some useful things
    }

    [Given(@"I run a useful step")]
    [When(@"I want to use a useful step")]
    public void IWantToUseAUsefulStep()
   {

    }

}

【讨论】:

  • 这将创建一个模棱两可的步骤定义以具有重复的Given 属性。
【解决方案2】:

这也感觉像是代码异味。为什么在When 步骤中运行Given 步骤?即使是额外的一行代码,也要让您的 GivenWhenThen 步骤完全分开:

Scenario: I test something useful
    Given I run a useful step                  # 1. Set up
    When I want to use a useful step           # 2. Act
    Then something useful should have happened # 3. Assert

如果您想在没有Given I run a useful step 提供的测试设置的情况下使用When I want to use a useful step 怎么办?

如果您确实需要每次运行某个Given,您可能需要使用场景背景来组织您的场景:

Scenario Background:
    Given I run a useful step                  # 1. Set up

Scenario: I test something useful
    When I want to use a useful step           # 2. Act
    Then something useful should have happened # 3. Assert

【讨论】:

  • 那么问题是,如果我有 10 个场景,我不希望每个场景都运行后台。背景只需要在“BeforeFeature”部分运行1。我只是想使用现有的步骤来实现这一点。但这看起来不太可能。
  • 我当然可以直接使用该函数,但随后 id 会丢失被调用步骤的上下文。我确实捕获了这些步骤的内容以用于记录目的
  • 如何丢失被调用步骤的上下文?你在用ScenarioContext.Current吗?你能发布更多你的步骤定义以及你想如何使用它们吗?我认为我们需要更多关于您的问题的背景知识。
  • 更新了更多信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-26
  • 2018-09-01
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多