Używam Moq i chcę utworzyć klasy budownicze, aby utworzyć moje makiety z ustawionymi rozsądnymi wartościami domyślnymi, które mogą w razie potrzeby nadpisać podczas konfiguracji testowej. Podejście, które podjąłem, wykorzystuje metody rozszerzania, w których przekazuję wartości parametrów wejściowych i oczekiwane wyniki. Czyniąc to, widzę inne zachowanie w tym, co wydaje mi się semantycznie równoważnym kodem: przekazywanie It.IsAny() bezpośrednio w konfiguracji vs przekazywanie wartości It.IsAny() pośrednio w konfiguracji. Przykład:Jaka jest różnica między przekazywaniem It.IsAny <int>() a wartością It.IsAny <int>() do metody konfiguracji
public interface IFoo
{
bool Bar(int value);
bool Bar2(int value);
}
public class Foo : IFoo
{
public bool Bar(int value) { return false; }
public bool Bar2(int value) { return false; }
}
var mock = new Mock<IFoo>();
mock.Setup(x => x.Bar(It.IsAny<int>())).Returns(true);
Assert.IsTrue(mock.Object.Bar(123)); // Succeeds
var myValue = It.IsAny<int>();
mock.Setup(x => x.Bar2(myValue)).Returns(true);
Assert.IsTrue(mock.Object.Bar2(123)); // Fails
Oba wywołania są równoważne (dla mnie), jednak wywołanie na Bar2 kończy się niepowodzeniem asercji. Dlaczego to?
Doskonałe wyjaśnienie, Ben. Miałem podejrzenie, że problem leży w ocenie wyrażenia, jak opisujesz, a nie w wartości zwracanej przez It.IsAny(). Spojrzałem na odzwierciedlenie źródła w ILSpy i mogłem zobaczyć It.IsAny , ale nie mogłem dostać mojej głowy owiniętej wokół jak to działało w odniesieniu do problemu. Jeszcze raz dziękuję za wyjaśnienie. –
Dzięki za oczyszczenie tych czarów dla mnie! Próbowałem powiedzieć "var anyFooParam = It.IsAny(); var anyBarParam = It.IsAny ();" aby sprawdzić, czy sprawiłoby, że moje testy byłyby bardziej czytelne, jak: .Setup (mock => mock.method (anyFooParam, anyBarParam)). Returns (something!) –