У меня есть две функции, которые используют общий шаг "When", но имеют разные шаги "Then" в разных классах.
Как получить доступ, например, ActionResult от моего вызова контроллера MVC в шаге "Когда" на моих двух шагах "Далее"?
У меня есть две функции, которые используют общий шаг "When", но имеют разные шаги "Then" в разных классах.
Как получить доступ, например, ActionResult от моего вызова контроллера MVC в шаге "Когда" на моих двух шагах "Далее"?
В SpecFlow 1.3 существует три метода:
Комментарии:
статические члены очень прагматичны и в этом случае не так злы, как мы, как разработчики могли бы сначала подумать (нет нити или необходимости для насмешек/замены в определениях шагов)
См. ответ от @Si Keep в этом потоке
Если конструктору класса определения шага нужны аргументы, Specflow пытается ввести эти аргументы. Это можно использовать для ввода одного и того же контекста в несколько этапов.
См. пример здесь:
https://github.com/techtalk/SpecFlow/wiki/Context-Injection
Используйте класс ScenarioContext, который является словарем, который является общим для всех этапов.
ScenarioContext.Current.Add("ActionResult", actionResult);
var actionResult = (ActionResult) ScenarioContext.Current["ActionResult"];
У меня есть вспомогательный класс, который позволяет мне писать
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 в настоящее время, похоже, вы получаете те же преимущества без необходимости определять расширение
Мне не нравилось использовать Scenario.Context из-за необходимости отбрасывать каждую словарную запись. Я нашел другой способ хранения и извлечения предмета без необходимости разыгрывать его. Однако здесь есть компромисс, потому что вы эффективно используете тип в качестве ключа для доступа к объекту из словаря ScenarioContext. Это означает, что может быть сохранен только один элемент этого типа.
TestPage testPageIn = new TestPage(_driver);
ScenarioContext.Current.Set<TestPage>(testPageIn);
var testPageOut = ScenarioContext.Current.Get<TestPage>();
Вы можете определить параметр в своих шагах, который является ключом к значению, которое вы храните. Таким образом, вы можете ссылаться на него в ваших последующих шагах, используя ключ.
...
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
Вы можете сохранить фактическое значение в словаре или в наборе свойств или подобном.