I have an "Test" class that has an IEnumerable of concrete objects
public class Test
{
public IEnumerable<MyObject> MyObjects { get; }
}
public class MyObject
{
public string Id { get; }
public MyObject(
string id,
{
this.Id = id;
}
}
When debugging my "Steps.cs" class used by my Specflow feature file, I noticed that the values for "Id" were changing. They were as expected in the "Given" step and I added these to the ScenarioContext
[Given("I have use case (.*)")]
{
var _test = _retrieveTest.GetMyObjects(useCase);
ScenarioContext.Current.Add("test", _test);
}
They were changed when I read them out of the ScenarioContext in the "When" Step
[When("I do something")]
public void WhenIDoSomething()
{
var _test = (MyProject.Entity.Test)ScenarioContext.Current["test"];
}
The solution to stop the values changing was to use the LINQ "ToList()" call when retrieving the object as shown below:
private IEnumerable<MyObject> GetMyObjects(
string usecase,
MyProject.Entity.Test test)
{
...
return testData.Objects
.Select(Object => {
var _id = var _id = Guid.NewGuid();
return new MyProject.Entity.MyObject(
_id);
}).ToList();
}
Can anyone explain why it is necessary to call ".ToList()" here and without it why the value of "Id" changes in the "ScenarioContext " between the "Given" and "When" steps
Without the .ToList() you have return an Enumerator that is executed everytime you iterate over it. With the .ToList() you materialize the enumerator and have a concrete list.
See IEnumerable vs List - What to Use? How do they work? for a more detailed answer.