Sto usando Moq e voglio creare classi di builder per creare i miei mock con predefiniti valori predefiniti preimpostati che possono essere sovrascritti durante l'impostazione della prova, se necessario. L'approccio che ho preso utilizza metodi di estensione in cui passo i valori dei parametri di input e l'output atteso. Nel fare ciò, sto vedendo un comportamento diverso in quello che a me sembra essere un codice semanticamente equivalente: passare It.IsAny() direttamente in una configurazione o passare il valore di It.IsAny() indirettamente in una configurazione. Esempio:Qual è la differenza tra il passaggio di It.IsAny <int>() e il valore di It.IsAny <int>() a un metodo di installazione
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
Le chiamate sono equivalenti (per me), ma la chiamata a Bar2 fallisce asserzione. Perchè è questo?
Ottima spiegazione, Ben. Avevo il sospetto che il problema risiedesse nella valutazione dell'espressione, come si descrive, piuttosto che nel valore di ritorno di It.IsAny(). Ho guardato la fonte riflessa in ILSpy e ho potuto vedere It.IsAny , ma non riuscivo a capire come funzionasse riguardo al problema. Grazie ancora per la spiegazione. –
Grazie per aver chiarito quella stregoneria per me! Stavo cercando di dire "var anyFooParam = It.IsAny(); var anyBarParam = It.IsAny ();" per vedere se renderebbe i miei test più leggibili come: .Setup (mock => mock.method (anyFooParam, anyBarParam)). Restituisce (qualcosa!) –