繁体   English   中英

使用Moq模拟扩展IList的接口

[英]Using Moq to mock an interface that extends IList

我正在尝试模拟扩展IList的接口,并使该模拟作为IEnumerable工作。 我期望模拟对象包含一个可枚举的用户列表,但该枚举不会产生任何结果。 如果我将接口ITestEnumerable扩展为IEnumerable而不是IList,则下面的代码有效。

public interface ITestEnumerable : IList<User>
{

}

[Fact]
public void TestTest()
{
    //Arrange
    var fakes = new List<User>()
    {
        new User() { DisplayName = "Joe Smith", Mail = "jsmith@test.com" },
        new User() { DisplayName = "Jane Doe", Mail = "jdoe@test.com" }
    };
    var mockTest = new Mock<ITestEnumerable>();
    mockTest.Setup(t => t.Count).Returns(() => fakes.Count());
    mockTest.Setup(t => t[It.IsAny<int>()]).Returns<int>(i => fakes.ElementAt(i));
    mockTest.As<IEnumerable<User>>().Setup(t => t.GetEnumerator()).Returns(() => fakes.GetEnumerator());
    var testList = new List<User>();

    //Act
    testList.AddRange(mockTest.Object);

    //Assert
    Assert.NotNull(testList[0]);
}

这里的问题出在AddRange函数的内部: https ://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,79de3e39e69a4811

您可以看到,第一个尝试是将其强制转换为ICollection,然后有一个完整的CopyTo流。

因此,最简单的方法是将其替换为类似的内容。 无论如何,您都可以进行模拟枚举。 也可以使用LINQ缩短它。

foreach(var item in mockTest.Object)
{
    testList.Add(item);
}

如果要使用最小起订量执行此操作,则应适合以下情况:

mockTest.As<ICollection<User>>().Setup(t => t.CopyTo(It.IsAny<User[]>(), It.IsAny<int>())).Callback<User[], int>((u,c) => fakes.CopyTo(u,c));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM