Метод установки объекта Mock для изменения входов и выходов, предупреждает: доступ к измененному закрытию - PullRequest
0 голосов
/ 21 декабря 2018

Я хочу установить фиктивный объект с методом, который должен возвращать что-то свое для каждого входа.Когда я попробовал что-то похожее на приведенный ниже код, я получил предупреждение о доступе к измененному закрытию (то есть о доступе к i).Как правильно настроить FooMethod(i) макета объекта для возврата i*3?

var ret = new Mock<FooClass>();

for(var i = 0; i < 10; i++){
    var bar = i*3;
    ret.Setup(x => x.FooMethod(i)).Returns(bar);
}

1 Ответ

0 голосов
/ 22 декабря 2018

Оливье уже сказал это в комментарии.Из-за семантики замыкания для переменной 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...