Skip to content

Commit

Permalink
change all relevant ScenarioContext.Current instances to Context-Inje…
Browse files Browse the repository at this point in the history
…ction (#2043)
  • Loading branch information
SabotageAndi authored Jul 8, 2020
1 parent 5802f26 commit 42f67df
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 86 deletions.
2 changes: 1 addition & 1 deletion docs/Bindings/Context-Injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public class BookSteps

The container used by SpecFlow can be customized, e.g. you can include object instances that have already been created, or modify the resolution rules.

You can customise the container from a [plugin](../Enhance/Plugins.md) or a before scenario [hook](Hooks.md). The class customising the injection rules has to obtain an instance of the scenario execution container (an instance of `BoDi.IObjectContainer`). This can be done through constructor injection (see example below) or by calling `ScenarioContext.Current.GetBindingInstance(typeof(BoDi.IObjectContainer))`.
You can customize the container from a [plugin](../Enhance/Plugins.md) or a before scenario [hook](Hooks.md). The class customizing the injection rules has to obtain an instance of the scenario execution container (an instance of `BoDi.IObjectContainer`). This can be done through constructor injection (see example below).

The following example adds the Selenium web driver to the container, so that binding classes can specify `IWebDriver` dependencies (a constructor argument of type `IWebDriver`).

Expand Down
33 changes: 17 additions & 16 deletions docs/Bindings/ScenarioContext.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,27 @@ This is the default behavior for a missing step definition, but you can also use

in the .feature:

Scenario: Pending step
When I set the ScenarioContext.Current to pending
Then this step will not even be executed
``` gherkin
Scenario: Pending step
When I set the current ScenarioContext to pending
Then this step will not even be executed
```

and the step definition:

[When("I set the ScenarioContext.Current to pending")]
public void WhenIHaveAPendingStep()
{
ScenarioContext.Pending();
}

[Then("this step will not even be executed")]
public void ThisStepWillNotBeExecuted()
{
throw new Exception("See!? This wasn't even thrown");
}


``` csharp
[When("I set the current ScenarioContext to pending")]
public void WhenIHaveAPendingStep()
{
ScenarioContext.Pending();
}

[Then("this step will not even be executed")]
public void ThisStepWillNotBeExecuted()
{
throw new Exception("See!? This wasn't even thrown");
}
```

## Storing data in the ScenarioContext

Expand Down
23 changes: 17 additions & 6 deletions docs/Bindings/Scoped-Step-Definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,21 @@ The following example shows a way to "ignore" executing the scenarios marked wit
You can define more complex filters using the [ScenarioContext](ScenarioContext.md) class. The following example starts selenium if the scenario is tagged with `@web` _and_ `@automated`.

``` c#
[BeforeScenario("web")]
public static void BeforeWebScenario()
{
if(ScenarioContext.Current.ScenarioInfo.Tags.Contains("automated"))
StartSelenium();
}
[Binding]
public class Binding
{
ScenarioContext _scenarioContext;

public Binding(ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
}

[BeforeScenario("web")]
public static void BeforeWebScenario()
{
if(_scenarioContext.ScenarioInfo.Tags.Contains("automated"))
StartSelenium();
}
}
```
170 changes: 107 additions & 63 deletions docs/Bindings/SpecFlow-Assist-Helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,24 @@ Then the person should have the following values
You can assert that the properties match with this simple step definition:

```c#
[Then("the person should have the following values")]
public void x(Table table){
// you don't have to get person this way, this is just for demo
var person = ScenarioContext.Current.Get<Person>();

table.CompareToInstance<Person>(person);
}
[Binding]
public class Binding
{
ScenarioContext _scenarioContext;

public Binding(ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
}

[Then("the person should have the following values")]
public void x(Table table){
// you don't have to get person this way, this is just for demo
var person = _scenarioContext.Get<Person>();

table.CompareToInstance<Person>(person);
}
}
```

If FirstName is not "John", LastName is not "Galt", or YearsOld is not 54, a descriptive error showing the differences is thrown.
Expand Down Expand Up @@ -147,12 +158,23 @@ Then I get back the following accounts
You can test you results with one call to CompareToSet<T>:

```c#
[Then("I get back the following accounts")]
public void x(Table table){
var accounts = ScenarioContext.Current.Get<IEnumerable<Account>>();

table.CompareToSet<Account>(accounts)
}
[Binding]
public class Binding
{
ScenarioContext _scenarioContext;

public Binding(ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
}

[Then("I get back the following accounts")]
public void x(Table table){
var accounts = _scenarioContext.Get<IEnumerable<Account>>();

table.CompareToSet<Account>(accounts)
}
}
```

In this example, `CompareToSet<T>` checks that two accounts are returned, and only tests the properties you defined in the table. **It does not test the order of the objects, only that one was found that matches.** If no record matching the properties in your table is found, an exception is thrown that includes the row number(s) that do not match up.
Expand Down Expand Up @@ -308,39 +330,50 @@ Consider the following steps:
With LINQ-based operations each of the above comparisons can be expressed using a single line of code

``` csharp
[When(@"I have a collection")]
public void WhenIHaveACollection(Table table)
{
var collection = table.CreateSet<Item>();
ScenarioContext.Current.Add("Collection", collection);
}

[Then(@"it should match")]
public void ThenItShouldMatch(Table table)
{
var collection = ScenarioContext.Current["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.RowCount == collection.Count() && table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should exactly match")]
public void ThenItShouldExactlyMatch(Table table)
{
var collection = ScenarioContext.Current["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.ToProjection<Item>().SequenceEqual(collection.ToProjection()));
}

[Then(@"it should not match")]
public void ThenItShouldNotMatch(Table table)
{
var collection = ScenarioContext.Current["Collection"] as IEnumerable<Item>;
Assert.IsFalse(table.RowCount == collection.Count() && table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should not exactly match")]
public void ThenItShouldNotExactlyMatch(Table table)
[Binding]
public class Binding
{
var collection = ScenarioContext.Current["Collection"] as IEnumerable<Item>;
Assert.IsFalse(table.ToProjection<Item>().SequenceEqual(collection.ToProjection()));
ScenarioContext _scenarioContext;

public Binding(ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
}

[When(@"I have a collection")]
public void WhenIHaveACollection(Table table)
{
var collection = table.CreateSet<Item>();
_scenarioContext.Add("Collection", collection);
}

[Then(@"it should match")]
public void ThenItShouldMatch(Table table)
{
var collection = _scenarioContext["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.RowCount == collection.Count() && table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should exactly match")]
public void ThenItShouldExactlyMatch(Table table)
{
var collection = _scenarioContext["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.ToProjection<Item>().SequenceEqual(collection.ToProjection()));
}

[Then(@"it should not match")]
public void ThenItShouldNotMatch(Table table)
{
var collection = _scenarioContext["Collection"] as IEnumerable<Item>;
Assert.IsFalse(table.RowCount == collection.Count() && table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should not exactly match")]
public void ThenItShouldNotExactlyMatch(Table table)
{
var collection = _scenarioContext["Collection"] as IEnumerable<Item>;
Assert.IsFalse(table.ToProjection<Item>().SequenceEqual(collection.ToProjection()));
}
}
```

Expand Down Expand Up @@ -368,25 +401,36 @@ In a similar way we can implement containment validation:
```

``` csharp
[Then(@"it should contain all items")]
public void ThenItShouldContainAllItems(Table table)
{
var collection = ScenarioContext.Current["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should not contain all items")]
public void ThenItShouldNotContainAllItems(Table table)
{
var collection = ScenarioContext.Current["Collection"] as IEnumerable<Item>;
Assert.IsFalse(table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should not contain any of items")]
public void ThenItShouldNotContainAnyOfItems(Table table)
[Binding]
public class Binding
{
var collection = ScenarioContext.Current["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.ToProjection<Item>().Except(collection.ToProjection()).Count() == table.RowCount);
ScenarioContext _scenarioContext;

public Binding(ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
}

[Then(@"it should contain all items")]
public void ThenItShouldContainAllItems(Table table)
{
var collection = _scenarioContext["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should not contain all items")]
public void ThenItShouldNotContainAllItems(Table table)
{
var collection = _scenarioContext["Collection"] as IEnumerable<Item>;
Assert.IsFalse(table.ToProjection<Item>().Except(collection.ToProjection()).Count() == 0);
}

[Then(@"it should not contain any of items")]
public void ThenItShouldNotContainAnyOfItems(Table table)
{
var collection = _scenarioContext["Collection"] as IEnumerable<Item>;
Assert.IsTrue(table.ToProjection<Item>().Except(collection.ToProjection()).Count() == table.RowCount);
}
}
```

Expand Down

0 comments on commit 42f67df

Please sign in to comment.