我有2个功能使用常见的“何时”步骤,但在不同的类中有不同的“然后”步骤。
如何在我的两个步骤中的When步骤中从我的MVC控制器调用中访问ActionResult?
答案 0 :(得分:34)
在SpecFlow 1.3中有三种方法:
评论:
静态成员非常务实,在这种情况下并不像开发人员首先想到的那样邪恶(在步骤定义中没有线程化或需要模拟/替换)
请参阅@Si Keep的回答
如果步骤定义类的构造函数需要参数,则Specflow会尝试注入这些参数。这可用于将相同的上下文注入到多个步骤定义中。
在这里看一个例子:
https://github.com/techtalk/SpecFlow/wiki/Context-Injection
答案 1 :(得分:33)
使用ScenarioContext类,它是所有步骤共有的字典。
ScenarioContext.Current.Add("ActionResult", actionResult);
var actionResult = (ActionResult) ScenarioContext.Current["ActionResult"];
答案 2 :(得分:15)
我有一个帮助类,可以让我写
Current<Page>.Value = pageObject;
是ScenarioContext的包装器。它取决于类型名称,因此如果您需要访问两个相同类型的变量,则需要进行一些扩展
public static class Current<T> where T : class
{
internal static T Value
{
get {
return ScenarioContext.Current.ContainsKey(typeof(T).FullName)
? ScenarioContext.Current[typeof(T).FullName] as T : null;
}
set { ScenarioContext.Current[typeof(T).FullName] = value; }
}
}
2019编辑:我现在会使用@ JoeT的答案,看起来你无需定义扩展即可获得相同的好处
答案 3 :(得分:8)
我不喜欢使用Scenario.Context,因为需要输出每个字典条目。我找到了另一种存储和检索项目的方法,无需投射它。但是,这里有一个权衡,因为您实际上是使用类型作为键从ScenarioContext字典访问对象。这意味着只能存储该类型的一个项目。
TestPage testPageIn = new TestPage(_driver);
ScenarioContext.Current.Set<TestPage>(testPageIn);
var testPageOut = ScenarioContext.Current.Get<TestPage>();
答案 4 :(得分:0)
您可以在步骤中定义一个参数,该参数是您存储的值的关键。这样,您可以使用密钥在后续步骤中引用它。
...
Then I remember the ticket number '<MyKey>'
....
When I type my ticket number '<MyKey>' into the search box
Then I should see my ticket number '<MyKey>' in the results
您可以将实际值存储在字典或属性包或类似内容中。
答案 5 :(得分:0)
由于这是我在Google上获得的第一个结果,所以我只是想提到@jbandi的答案是最完整的。但是,从3.0版或更高版本开始:
在SpecFlow 3.0中,我们将ScenarioContext.Current和FeatureContext.Current标记为已过时,以明确表示您以后应该避免使用这些属性。离开这些属性的原因是,在并行运行方案时它们不起作用。
(ScenarioContext and FeatureContext in SpecFlow 3.0 and Later)
因此,在测试期间存储数据的最新方法是使用Context Injection。我会添加示例代码,但实际上链接中的示例代码非常出色,因此请查看。
您可以通过将实例注入绑定类来模仿现在已经过时的ScenarioContext.Current。
[Binding]
public class MyStepDefs
{
private readonly ScenarioContext _scenarioContext;
public MyStepDefs(ScenarioContext scenarioContext)
{
_scenarioContext= scenarioContext ;
}
public SomeMethod()
{
_scenarioContext.Add("key", "value");
var someObjectInstance = new SomeObject();
_scenarioContext.Set<SomeObject>(someObjectInstance);
_scenarioContext.Get<SomeObject>();
// etc.
}
}