Osservando lo source code of It
, ha a che fare con gli alberi di espressione. Mi piace la domanda; possono essere piuttosto sconcertanti. Se volete dare un'occhiata alle seguenti definizioni dei metodi:
public static TValue It.Is<TValue>(Expression<Func<TValue, bool>> match)
{
return Match<TValue>.Create(
value => match.Compile().Invoke(value),
() => It.Is<TValue>(match));
}
public static T Match.Create<T>(Predicate<T> condition, Expression<Func<T>> renderExpression)
{
// ...
return default(T);
}
Se si desidera eseguire la seguente riga:
var zombieDisconnectParameterMatcher = It.Is<ControllUser>(x => x.Zombies[0].ConnectionId == null);
Poi It.Is<ControllUser>()
cercherà di chiamare un metodo chiamato Match.Create<ControllUser>()
, che restituisce il valore predefinito di ControllUser
. Presumo che ControllUser
sia una classe e pertanto zombieDisconnectParameterMatcher
sarà null
. Dovresti essere in grado di vederlo con il debugger. Quindi, quello che in realtà si sta chiamando è:
hub.MockedUserRepository.Setup(r => r.Update(null))
.Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null)))
.Verifiable();
Quando si esegue il metodo Update
con un non-null ControllUser
(dal metodo che è in fase di test, per esempio), la richiamata non si innescherà. Semplicemente non corrisponde ai criteri poiché non è nulla. Vedresti che anche la verifica fallisce.
Per risolvere questo problema, allineare la variabile zombieDisconnectParameterMatcher
o trasformarla in una variabile di tipo expression (ad esempio). Quest'ultimo farà in modo che il codice non venga eseguito, ma trattato come un'espressione a cui il framework mock può ragionare ('è Zombies[0].ConnectionId == null
chiamato con Zombies[0].ConnectionId == null
?).
Mi inchino in segno di riverenza a voi, signore @ Caramiriel. – fernandoespinosa