如何使用 NSubstitute 设置 IEnumerable 类的返回值

Pet*_*PH' 7 c# unit-testing nsubstitute

我有这个域名:

public class ADomainClass
{
    public int Id { get; set; }
}

public interface IMyClass : IEnumerable<ADomainClass>
{
}

public class MyClass : IMyClass
{
    public IEnumerator<ADomainClass> GetEnumerator()
    {
        IList<ADomainClass> list = new List<ADomainClass>();
        //list = GetData...();

        foreach (var item in list)
        {
            yield return item;
        }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

并想要构建以下测试:

[Test]
public void TestSample()
{
    //Arrange
    IMyClass myclass = Substitute.For<IMyClass>();
    IList<ADomainClass> testdata = new List<ADomainClass>()
    {
        new ADomainClass(){ Id = 1, },
        new ADomainClass(){ Id = 2, },
        new ADomainClass(){ Id = 3, },
        new ADomainClass(){ Id = 4, },
    };
    int count = 0;

    myclass.ReturnsForAnyArgs(testdata); //How to set the "return" value?

    //Act
    foreach (ADomainClass item in myclass)
    {
        count++;
    }

    //Assert
    count.Should().Be(testdata.Count);
}
Run Code Online (Sandbox Code Playgroud)

设置方法的返回值很容易,如下所示:

myclass.GetData().Returns(data);
Run Code Online (Sandbox Code Playgroud)

我不记得当它是可枚举类时如何设置返回值。我以前解决过一次,但不记得在哪里使用过它。

Tvd*_*vdH 6

我的问题是 NSubstitute 存储枚举的状态,因此如果您在测试的系统中使用枚举器两次,它将在第二次继续使用第二个元素。我使用类似下面的代码作为解决方法(使用 lambda 而不是返回枚举器,第 1 + 2 行仅用于演示)。我只用一些 Linq 和 foreach 对此进行了测试。

var bar = new List<string> { "a", "b", "c" };
var foo = Substitute.For<ICollection<string>>();
foo.GetEnumerator().Returns((ci) => { return bar.GetEnumerator(); });
Run Code Online (Sandbox Code Playgroud)


for*_*rir 4

您只需要告诉您的替代者从您的测试数据中返回枚举器:

myclass.GetEnumerator().Returns(testdata.GetEnumerator());
Run Code Online (Sandbox Code Playgroud)

  • 这不会按预期工作。您需要使用 lambda (请参阅@TvdH 答案)每次返回一个新的枚举器。否则,枚举器将不会在多次调用之间重置。 (3认同)