修改现有设置的 Returns

Modify Returns of existing Setup

假设我有一个如下所示的标准设置:

mock.Setup(myObj => myObj.MyMethod(It.Is<MyT>(item => IsTrue(item)))).Returns(someList)

是否可以在单独的代码行中识别完全相同的 Setup(使用相同的 It.Is 条件模拟相同的方法),然后修改 Returns?例如,假设在一种情况下我想要 MyMethod 到 return 列表 {0,1,2} 然后我确定在相同的条件下我也想要 return {3 ,4,5}。由于代码的结构方式,我不知道 {3,4,5} 先验,所以我不能在初始设置中使用它。

您可以像这样将委托传递给 Returns:

mock.Setup(myObj => myObj.MyMethod(It.Is<MyT>(item => IsTrue(item)))).Returns(item => (condition) ? list1 : list2)

你可以这样做:

var someList = new List<int> { 0, 1, 2, };
mock.Setup(myObj => myObj.MyMethod(It.Is<MyT>(item => IsTrue(item))))
  .Returns(someList);

// use 'mock' first time(s)

someList.Clear();  // if wanted
someList.AddRange(new[] { 3, 4, 5, });

// use 'mock' additional time(s)

之所以有效,是因为 List<> 是引用类型。 Moq 只记得对 List<> 对象所在位置的引用。如果您改变 List<> 对象(不更改对 new List<int> 的引用!),那很好。

另一方面,如果您想更改对不同对象(另一个实例)的引用,请使用 lambda(几乎就像 Spritely 的回答):

var someList = new List<int> { 0, 1, 2, };
mock.Setup(myObj => myObj.MyMethod(It.Is<MyT>(item => IsTrue(item))))
  .Returns(() => someList);

// use 'mock' first time(s)

someList = new List<int> { 3, 4, 5, };

// use 'mock' additional time(s)

在我的第二个解决方案中,观察箭头 () => someList