是否可以模拟 Specflow 的 ScenarioContext? (C#)
Is it possible to Mock Specflow's ScenarioContext? (C#)
正在尝试为使用 ScenarioContext 的 Specflow 步骤编写单元测试。此步骤试图从 ScenarioContext 中检索 属性 的值。是否可以模拟 ScenarioContext,以便我可以为此 属性 设置一个值?
在我的本地使用 VS 专业和 Moq 框架。谢谢
据我所知,ScenarioContext 没有实现任何接口。在 ScenarioContext 上尝试 Mock 失败(原因在下面的代码块中)
private Mock<IPropertyBucket> _propertyBucket;
ctor(){
var mo = new Mock<ScenarioContext>(); // this line fails as ScenarioContext has no public contructor.
mo.Object.Add("response", Response); // this property is what the specflow step is using eventually
_propertyBucket = new Mock<IPropertyBucket>();
_propertyBucket.Setup(pb => pb.ScenarioContext).Returns(mo.Object);
}
仅供参考:我正在研究多框架目标解决方案。该框架适用于 net472 和 netCore3。1.x。 ScenarioContext 的实现在.Net Core 和.Net framework 中是不同的。
发布我最终采用的伪代码,它在过去的一年里对我很有用,无需进行任何更改。
基本上是围绕 ScenarioContext 创建了一个包装器,它有一个 ScenarioContext 的私有实例(以下代码中的 MyScenarioContext),现在只公开了所需的方法。不用说,包装器绑定了一个接口,它允许一起模拟 ScenarioContext。
public class ScenarioContext : IScenarioContext
{
public ScenarioContext(TechTalk.SpecFlow.ScenarioContext scenarioContext)
{
MyScenarioContext = scenarioContext;
}
private TechTalk.SpecFlow.ScenarioContext MyScenarioContext { get; }
public IObjectContainer ScenarioContainer => MyScenarioContext.ScenarioContainer;
public StepInfo StepInfo => MyScenarioContext.StepContext.StepInfo;
ScenarioInfo IScenarioContext.ScenarioInfo => MyScenarioContext.ScenarioInfo;
public bool Clear(string propertyName)
{
if (!MyScenarioContext.ContainsKey(propertyName)) return false;
MyScenarioContext.Remove(propertyName);
return true;
}
public T GetProperty<T>(string key)
{
if (MyScenarioContext.ContainsKey(key))
return (T)MyScenarioContext[key];
throw new Exception($"No key remembered with the name {key}");
}
//.
//.
//.
// Other useful functions such as Remember etc.
}
正在尝试为使用 ScenarioContext 的 Specflow 步骤编写单元测试。此步骤试图从 ScenarioContext 中检索 属性 的值。是否可以模拟 ScenarioContext,以便我可以为此 属性 设置一个值?
在我的本地使用 VS 专业和 Moq 框架。谢谢
据我所知,ScenarioContext 没有实现任何接口。在 ScenarioContext 上尝试 Mock 失败(原因在下面的代码块中)
private Mock<IPropertyBucket> _propertyBucket;
ctor(){
var mo = new Mock<ScenarioContext>(); // this line fails as ScenarioContext has no public contructor.
mo.Object.Add("response", Response); // this property is what the specflow step is using eventually
_propertyBucket = new Mock<IPropertyBucket>();
_propertyBucket.Setup(pb => pb.ScenarioContext).Returns(mo.Object);
}
仅供参考:我正在研究多框架目标解决方案。该框架适用于 net472 和 netCore3。1.x。 ScenarioContext 的实现在.Net Core 和.Net framework 中是不同的。
发布我最终采用的伪代码,它在过去的一年里对我很有用,无需进行任何更改。
基本上是围绕 ScenarioContext 创建了一个包装器,它有一个 ScenarioContext 的私有实例(以下代码中的 MyScenarioContext),现在只公开了所需的方法。不用说,包装器绑定了一个接口,它允许一起模拟 ScenarioContext。
public class ScenarioContext : IScenarioContext
{
public ScenarioContext(TechTalk.SpecFlow.ScenarioContext scenarioContext)
{
MyScenarioContext = scenarioContext;
}
private TechTalk.SpecFlow.ScenarioContext MyScenarioContext { get; }
public IObjectContainer ScenarioContainer => MyScenarioContext.ScenarioContainer;
public StepInfo StepInfo => MyScenarioContext.StepContext.StepInfo;
ScenarioInfo IScenarioContext.ScenarioInfo => MyScenarioContext.ScenarioInfo;
public bool Clear(string propertyName)
{
if (!MyScenarioContext.ContainsKey(propertyName)) return false;
MyScenarioContext.Remove(propertyName);
return true;
}
public T GetProperty<T>(string key)
{
if (MyScenarioContext.ContainsKey(key))
return (T)MyScenarioContext[key];
throw new Exception($"No key remembered with the name {key}");
}
//.
//.
//.
// Other useful functions such as Remember etc.
}