El escenario es el siguiente: un usuario realiza alguna acción (como ganar una insignia o desbloquear algo) y se envía una notificación por correo electrónico. Una para el usuario (con un mensaje como "Has desbloqueado XYZ ...") y luego un mensaje diferente para cada uno de sus amigos como ("Tu amigo ha desbloqueado XYZ ...").Cómo verificar varias llamadas a métodos con Moq
public interface INotify
{
void Notify(User user, User friend);
}
public class NotificationService
{
private IEnumerable<INotify> _notifiers;
public NotificationService(IEnumerable<INotify> notifiers)
{
_notifiers = notifiers;
}
public SendNotifications()
{
User user = GetUser();
IEnumerable<User> friends = GetFriends();
foreach(var notifier in _notifiers)
{
//Send notification to user
notifier.Notify(user, null);
//send notification to users friends
foreach(var friend in friends)
notifier.Notify(user, friend);
}
}
}
Estoy tratando de usar moq para probar que cada notificador se llama 2x. Una vez pasando null como el segundo parámetro y la segunda vez pasando un valor a ambos parámetros.
[Test]
public void MakeSureEveryoneIsNotified()
{
var notifierMock = new Mock<INotifier>();
var svc = new NotificationService(new List<INotifier>{ notifierMock.Object });
svc.SendNotifications();
notifierMock.Verify(x => x.Notify(It.Is<User>(user => user.UserId == 1), null), Times.Once());
notifierMock.Verify(x => x.Notify(It.Is<User>(user => user.UserId == 1), It.Is<User>(user => user.UserId == 2)), Times.Once());
}
El problema es que la segunda llamada de verificación arroja una ArgumentNullException para el segundo parámetro. ¿Hay algo que decir "Compruebe que la primera llamada tiene estos parámetros, y luego la segunda llamada tiene otros parámetros". Sé que puedo solucionarlo simplemente llamando al:
notifierMock.Verify(x => x.Notify(It.IsAny<User>(), It.IsAny<User>()), Times.Exactly(2));
Pero quería ser un poco más específico. ¿Alguna forma de hacer esto?
¿Ha intentado recrear a un Usuario fuera de la declaración .Verify y usar ese Usuario como argumento? –
Quitaría la dependencia del método GetUser(), crearía un proveedor de usuario, se burlaría de él y luego uniría las partes relevantes del proveedor. –
El método GetUser es realmente de una dependencia externa que se inyecta en la clase, pero lo dejé para abreviar. La primera opción debería funcionar – Micah