В SpecFlow, как я могу обмениваться данными между шагами / функциями? - PullRequest
34 голосов
/ 21 мая 2010

У меня есть 2 функции, которые используют общий шаг «когда», но имеют разные шаги «тогда» в разных классах.

Как мне получить доступ, например, к ActionResult из моего вызова контроллера MVC в когдашаг в мои два шага?

Ответы [ 5 ]

34 голосов
/ 03 июня 2010

В SpecFlow 1.3 есть три метода:

  1. статические элементы
  2. ScenarioContext
  3. ContextInjection

Комментарии:

  1. статические члены очень прагматичны и в этом случае не так злы, как мы, как разработчики могли бы сначала подумать (нет потоков или необходимости насмешек / замен в определениях шагов)

  2. См. Ответ @Si Keep в этой теме

  3. Если конструктор класса определения шага нуждается в аргументах, Specflow пытается внедрить эти аргументы. Это может быть использовано для введения одного и того же контекста в несколько определений шагов.
    Смотрите пример здесь: https://github.com/techtalk/SpecFlow/wiki/Context-Injection

33 голосов
/ 21 мая 2010

Используйте класс ScenarioContext, который является словарем, общим для всех шагов.

ScenarioContext.Current.Add("ActionResult", actionResult);
var actionResult = (ActionResult) ScenarioContext.Current["ActionResult"];
15 голосов
/ 20 декабря 2012

У меня есть вспомогательный класс, который позволяет мне писать

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 edit: я бы использовал ответ @ JoeT в настоящее время, похоже, вы получаете те же преимущества без необходимости определять расширение

8 голосов
/ 06 июля 2015

Мне не нравилось использовать Scenario.Context из-за необходимости отбрасывать каждую словарную запись. Я нашел другой способ хранения и извлечения предмета без необходимости разыгрывать его. Однако здесь есть компромисс, потому что вы эффективно используете тип в качестве ключа для доступа к объекту из словаря ScenarioContext. Это означает, что может быть сохранен только один элемент этого типа.

TestPage testPageIn = new TestPage(_driver);
ScenarioContext.Current.Set<TestPage>(testPageIn);
var testPageOut = ScenarioContext.Current.Get<TestPage>();
0 голосов
/ 15 января 2018

Вы можете определить параметр в ваших шагах, который является ключом к значению, которое вы сохраняете. Таким образом, вы можете ссылаться на него в ваших последующих шагах, используя ключ.

...
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 

Вы можете сохранить фактическое значение в словаре или в наборе свойств или подобном.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...