简体   繁体   English

使用Moq模拟扩展IList的接口

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

I am attempting to mock an interface that extends IList and get the mock to work as an IEnumerable. 我正在尝试模拟扩展IList的接口,并使该模拟作为IEnumerable工作。 I was expecting the mocked object to contain an enumerable list of users, instead the enumeration yields no results. 我期望模拟对象包含一个可枚举的用户列表,但该枚举不会产生任何结果。 The code below works if I change the interface ITestEnumerable extends to IEnumerable instead of IList. 如果我将接口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]);
}

The problem here is in the internals of AddRange function: https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,79de3e39e69a4811 这里的问题出在AddRange函数的内部: https ://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,79de3e39e69a4811

You can see, that first attempt is to cast it to ICollection and then there is a whole CopyTo flow. 您可以看到,第一个尝试是将其强制转换为ICollection,然后有一个完整的CopyTo流。

So the easiest would be to replace it with something like this. 因此,最简单的方法是将其替换为类似的内容。 You do mock enumerator anyway. 无论如何,您都可以进行模拟枚举。 It can also be shortened with LINQ. 也可以使用LINQ缩短它。

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

If you want to do this with MOQ, something like this should fit: 如果要使用最小起订量执行此操作,则应适合以下情况:

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