Mock class 继承自 IReadOnlyCollection
Mock class which inherits from IReadOnlyCollection
我想模拟一个继承自 IReadOnlyCollection 的 class。我写了一些示例代码来演示我的问题。三项断言中有两项有效。
当我将模拟的 IRemainingSteps 转换为列表或使用 LINQ 时,列表为空。
请你解释一下我应该如何更改 GetEnumerator 的设置以允许所有三个断言通过。
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Moq;
using NUnit.Framework;
namespace BranchScript.UT
{
[TestFixture]
public class Steps
{
[Test]
public void Test()
{
// Arrange
string branchA = "branch a";
string branchB = "branch b";
var mockStep1 = new Mock<IRemainingStep>();
mockStep1.Setup(x => x.StepNotes).Returns(branchA);
var mockStep2 = new Mock<IRemainingStep>();
mockStep2.Setup(x => x.StepNotes).Returns(branchB);
var mockStep3 = new Mock<IRemainingStep>();
mockStep3.Setup(x => x.StepNotes).Returns(branchA);
var mockStep4 = new Mock<IRemainingStep>();
mockStep4.Setup(x => x.StepNotes).Returns(branchB);
List<IRemainingStep> mockStepList = new List<IRemainingStep>
{
mockStep1.Object,
mockStep2.Object,
mockStep3.Object,
mockStep4.Object
};
var refs = new Mock<IRemainingSteps>(MockBehavior.Strict);
refs.Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
refs.As<IEnumerable>().Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
var mockPlate = new Mock<IPlate>();
mockPlate.Setup(x => x.RemainingSteps).Returns(refs.Object);
// Assert
Assert.AreEqual(branchA, mockPlate.Object.RemainingSteps.First().StepNotes); // Pass
Assert.AreEqual(branchB, mockPlate.Object.RemainingSteps.Last().StepNotes); // Pass
Assert.AreEqual(2, mockPlate.Object.RemainingSteps.Where(x => x.StepNotes == branchA).Count()); // Fail
}
}
public interface IRemainingSteps : IReadOnlyCollection<IRemainingStep>
{
}
public interface IRemainingStep : IStep
{
}
public interface IStep
{
string StepNotes { get; }
}
public interface IPlate
{
IRemainingSteps RemainingSteps { get; }
}
}
传回 Enumerator 只允许读取一次,因为它是只向前的。
var refs = new Mock<IRemainingSteps>(MockBehavior.Strict);
refs.Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
refs.As<IEnumerable>().Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
但是如果模拟returns一个函数,它将允许重复调用枚举器
var refs = new Mock<IRemainingSteps>(MockBehavior.Strict);
refs.Setup(r => r.GetEnumerator()).Returns(() => mockStepList.GetEnumerator());
refs.As<IEnumerable>().Setup(r => r.GetEnumerator()).Returns(() => mockStepList.GetEnumerator());
注意Returns
中函数调用的使用
.Returns(() => mockStepList.GetEnumerator())
前两个断言有效,因为您仍在枚举器中前进。
Assert.AreEqual(branchA, mockPlate.Object.RemainingSteps.First().StepNotes); // Pass
Assert.AreEqual(branchB, mockPlate.Object.RemainingSteps.Last().StepNotes); // Pass
根据第三个断言,指针已经在末尾
Assert.AreEqual(2, mockPlate.Object.RemainingSteps.Where(x => x.StepNotes == branchA).Count()); // Fail
所以计数不会像预期的那样。
我想模拟一个继承自 IReadOnlyCollection 的 class。我写了一些示例代码来演示我的问题。三项断言中有两项有效。
当我将模拟的 IRemainingSteps 转换为列表或使用 LINQ 时,列表为空。
请你解释一下我应该如何更改 GetEnumerator 的设置以允许所有三个断言通过。
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Moq;
using NUnit.Framework;
namespace BranchScript.UT
{
[TestFixture]
public class Steps
{
[Test]
public void Test()
{
// Arrange
string branchA = "branch a";
string branchB = "branch b";
var mockStep1 = new Mock<IRemainingStep>();
mockStep1.Setup(x => x.StepNotes).Returns(branchA);
var mockStep2 = new Mock<IRemainingStep>();
mockStep2.Setup(x => x.StepNotes).Returns(branchB);
var mockStep3 = new Mock<IRemainingStep>();
mockStep3.Setup(x => x.StepNotes).Returns(branchA);
var mockStep4 = new Mock<IRemainingStep>();
mockStep4.Setup(x => x.StepNotes).Returns(branchB);
List<IRemainingStep> mockStepList = new List<IRemainingStep>
{
mockStep1.Object,
mockStep2.Object,
mockStep3.Object,
mockStep4.Object
};
var refs = new Mock<IRemainingSteps>(MockBehavior.Strict);
refs.Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
refs.As<IEnumerable>().Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
var mockPlate = new Mock<IPlate>();
mockPlate.Setup(x => x.RemainingSteps).Returns(refs.Object);
// Assert
Assert.AreEqual(branchA, mockPlate.Object.RemainingSteps.First().StepNotes); // Pass
Assert.AreEqual(branchB, mockPlate.Object.RemainingSteps.Last().StepNotes); // Pass
Assert.AreEqual(2, mockPlate.Object.RemainingSteps.Where(x => x.StepNotes == branchA).Count()); // Fail
}
}
public interface IRemainingSteps : IReadOnlyCollection<IRemainingStep>
{
}
public interface IRemainingStep : IStep
{
}
public interface IStep
{
string StepNotes { get; }
}
public interface IPlate
{
IRemainingSteps RemainingSteps { get; }
}
}
传回 Enumerator 只允许读取一次,因为它是只向前的。
var refs = new Mock<IRemainingSteps>(MockBehavior.Strict);
refs.Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
refs.As<IEnumerable>().Setup(r => r.GetEnumerator()).Returns(mockStepList.GetEnumerator());
但是如果模拟returns一个函数,它将允许重复调用枚举器
var refs = new Mock<IRemainingSteps>(MockBehavior.Strict);
refs.Setup(r => r.GetEnumerator()).Returns(() => mockStepList.GetEnumerator());
refs.As<IEnumerable>().Setup(r => r.GetEnumerator()).Returns(() => mockStepList.GetEnumerator());
注意Returns
.Returns(() => mockStepList.GetEnumerator())
前两个断言有效,因为您仍在枚举器中前进。
Assert.AreEqual(branchA, mockPlate.Object.RemainingSteps.First().StepNotes); // Pass
Assert.AreEqual(branchB, mockPlate.Object.RemainingSteps.Last().StepNotes); // Pass
根据第三个断言,指针已经在末尾
Assert.AreEqual(2, mockPlate.Object.RemainingSteps.Where(x => x.StepNotes == branchA).Count()); // Fail
所以计数不会像预期的那样。