khe*_*bie 3 cucumber specflow gherkin
我正在使用specflow指定我的应用程序,它只是让我从做非常糟糕的事情,所以我真的很喜欢它:-)但是我对步骤之间的耦合有问题:例如,因为我在一个人中使用模拟器我告诉模拟它应该返回一个实体,但在另一个我告诉模拟返回相同的实体,但与另一个属性.
看看这一步(从以下Darrens的答案中被盗并修改):
Given a guy the following guy exists:
| Name | Age | Salary |
| John Doe | 42 | 400 |
When his salary changes to 420
And I run the paycheck program
Then he should be paid 420
Run Code Online (Sandbox Code Playgroud)
看到这里我从一个Guy对象开始,然后修改对象 - 这是我正在测试的东西.
所以我将一个实体放入模拟存储库,然后在另一个步骤中将其拉出并再次放入.如何避免步骤之间的高耦合和可重用性?
当然,我可以在方案类中保留一个局部变量,并将所有实体放在该变量中,但我会将这些步骤结合起来.
我避免耦合和促进可重用性的方式是:
1.)按实体分组我的步骤,如AccountRepositorySteps(对于AccountRepository)或AccountControllerSteps(对于AccountController).
2.)制作步骤取决于抽象,而不是混凝土(就像我们的生产代码一样).
3.)利用当前的ScenarioContext在步骤和步骤文件之间传递值.
这是一个简短的例子:
Given a guy with the name Darren exists
And a guy with the name John exists
When I hit the guy page
Then I should see two guys
Run Code Online (Sandbox Code Playgroud)
RepositorySteps.cs
private List<string> guys;
[BeforeScenario]
public void Setup(){
guys = new List<string>();
var fake = new Mock<IRepository>();
fake.Setup(x=>x.GetGuys()).Returns(guys);
ScenarioContext.Current.Set(fake) // Mock<IRepository>
ScenarioContext.Current.Set(fake.Object); // IRepository
}
[Given("a guy with the name '(.*)' exists"]
public void a(string guy){
guys.Add(guy);
// and if I need to pull out the mock, I can do it like so
var fake = ScenarioContext.Current.Get<Mock<IRepository>>();
}
Run Code Online (Sandbox Code Playgroud)
GuyController.cs
When["I hit the guy page"]
public void x(){
var repository = ScenarioContext.Current.Get<IRepository>();
var controller = new GuyController(repository);
var result = controller.Index();
ScenarioContext.Current.Set(result);
}
Run Code Online (Sandbox Code Playgroud)
看,这里GuyController获取该模拟对象的步骤,但他不知道它是一个模拟.这只是他的一个IRepository.如果由于某种原因,你需要加载IRepository真实的版本库,并希望运行规范,所有你需要做的是与真实IRepository加载ScenarioContext.
遵循这种模式,我的步骤非常分离,并且不受我对其他人所做的更改的影响.它比我在使用SpecFlow时所做的技巧要好得多,我在同一步骤文件中使用静态方法或组合无关的步骤.
| 归档时间: |
|
| 查看次数: |
1396 次 |
| 最近记录: |