Heinrich;
Make sure you mock out the correct GetEnumerator. If your subject
under test uses IEnumerable rather than IEnumerable<T>, you'll need to
downcast your substitute to IEnumerable when calling Returns().
See the code below:
In TryEnumerableOfT_With_OfType, the final line crashes with
NullReferenceException because System.Linq.Enumerable.OfType extends
IEnumerable, not IEnumerable<T>.
In TryEnumerableOfT_With_OfType_UsingCasting, we downcast the
substitute to IEnumerable when calling Returns(). The call to OfType()
succeeds, and we get the results we expect.
Yours,
Garth.
[Explicit("Tests a dependency, not our code.")]
[TestFixture]
public class Test_NSubstitute_WithEnumerables {
[Test]
public void TryEnumerableOfT() {
List<object> actual = new List<object>() { "fnord" };
IEnumerable<object> subject =
Substitute.For<IEnumerable<object>>();
subject.GetEnumerator().Returns(actual.GetEnumerator());
List<object> enumerationResults = subject.ToList();
subject.Received().GetEnumerator();
Assert.AreEqual(actual, enumerationResults);
}
[Test]
[ExpectedException(typeof(NullReferenceException))]
public void TryEnumerableOfT_With_OfType() {
List<object> actual = new List<object>() { "fnord" };
IEnumerable<object> subject =
Substitute.For<IEnumerable<object>>(); // oops!
subject.GetEnumerator().Returns(actual.GetEnumerator());
var enumerationResults =
subject.OfType<string>().ToList(); // you did it wrong
}
[Test]
public void TryEnumerableOfT_With_OfType_UsingCasting() {
List<object> actual = new List<object>() { "fnord" };
IEnumerable<object> subject =
Substitute.For<IEnumerable<object>>();
((IEnumerable)
subject).GetEnumerator().Returns(actual.GetEnumerator()); // better
var enumerationResults =
subject.OfType<string>().ToList();
((IEnumerable) subject).Received().GetEnumerator();
Assert.AreEqual(actual, enumerationResults);
}
[Test]
public void TryGenericInterfaceDerivedFromEnumerableOfT() {
List<object> actual = new List<object>() { "fnord" };
var subject =
Substitute.For<IEnumerateAndAddValue<object>>();
subject.GetEnumerator().Returns(actual.GetEnumerator());
List<object> enumerationResults = subject.ToList();
subject.Received().GetEnumerator();
Assert.AreEqual(actual, enumerationResults);
}
public interface IEnumerateAndAddValue<T> : IEnumerable<T> {
void AddValue();
}
[Test]
public void TryNonGenericInterfaceDerivedFromEnumerableOfT() {
List<object> actual = new List<object>() { "fnord" };
var subject =
Substitute.For<IEnumerateObjectsAndAddValue>();
subject.GetEnumerator().Returns(actual.GetEnumerator());
List<object> enumerationResults = subject.ToList();
Assert.AreEqual(actual, enumerationResults);
subject.Received().GetEnumerator();
}
public interface IEnumerateObjectsAndAddValue :
IEnumerable<object> {
void AddValue();