Оливье уже сказал это в комментарии.Из-за семантики замыкания для переменной for
то, что Moq видит в вашем коде, действительно:
ret.Setup(x => x.FooMethod(10)).Returns(0);
ret.Setup(x => x.FooMethod(10)).Returns(3);
ret.Setup(x => x.FooMethod(10)).Returns(6);
ret.Setup(x => x.FooMethod(10)).Returns(9);
ret.Setup(x => x.FooMethod(10)).Returns(12);
ret.Setup(x => x.FooMethod(10)).Returns(15);
ret.Setup(x => x.FooMethod(10)).Returns(18);
ret.Setup(x => x.FooMethod(10)).Returns(21);
ret.Setup(x => x.FooMethod(10)).Returns(24);
ret.Setup(x => x.FooMethod(10)).Returns(27);
Конечно, это не то, что вам нужно.(Moq будет установлен только для значения 10
, и при этом он будет использовать самую последнюю Setup
, следовательно, вернет 27
.)
Не закрывать (захватывать) for
переменная.Одно из исправлений:
for (var i = 0; i < 10; i++) {
var iCopy = i;
ret.Setup(x => x.FooMethod(iCopy)).Returns(3 * iCopy);
}
В более новых версиях C # цикл foreach
отличается.Таким образом, это работает:
foreach (var i in Enumerable.Range(0, 10)) {
ret.Setup(x => x.FooMethod(i)).Returns(3 * i);
}
Moq предлагает другой метод, где вам не нужен цикл.Это так:
ret.Setup(x => x.FooMethod(It.IsAny<int>())).Returns((int i) => 3 * i);
Конечно, это настроено на все i
.Если вы не хотите этого, вы можете изменить на:
ret.Setup(x => x.FooMethod(It.Is((int i) => 0 <= i && i < 10))).Returns((int i) => 3 * i);