Способ, которым я избегаю связывания и продвигаю возможность повторного использования, заключается в следующем:
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
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>>();
}
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);
}
См. Здесь шаг дляGuyController получает этот фиктивный объект, но он не знает, что это фиктивный объект.Это просто IRepository для него.И если по какой-то причине вам необходимо загрузить REAL-репозиторий для IRepository и запустить свои спецификации, все, что вам нужно сделать, это загрузить ScenarioContext с реальным IRepository.
Следуя этому шаблону, мои шагиочень отделен и защищен от изменений, которые я делаю другим.Он работает намного лучше, чем трюки, которые я делал в начале своего использования SpecFlow, где я использовал статические методы или группировал несвязанные шаги в одном файле шагов.