Reputation: 19356
I am doing some tests to learn about how to mock methods that use dialog boxes. I have this classes:
My Interface, that is a wrapper for the MessageBox.
public interface IDialogoDummy
{
ResultadoDialogo dummy(string paramMensaje, string paramCaption, System.Windows.MessageBoxButton paramBotones, MessageBoxResult paramBotonPorDefecto);
}
The class that implements my interface:
public class DialogoDummy : IDialogoDummy
{
//El método tiene que ser virtual para que moq pueda utilizarlo
public virtual ResultadoDialogo dummy(string paramMensaje, string paramCaption, System.Windows.MessageBoxButton paramBotones, MessageBoxResult paramBotonPorDefecto)
{
MessageBoxResult resultado = System.Windows.MessageBox
.Show(paramMensaje,
paramCaption,
paramBotones,
MessageBoxImage.None,
paramBotonPorDefecto);
if(resultado == MessageBoxResult.Cancel)
{
return ResultadoDialogo.Cancel;
}
else if(resultado == MessageBoxResult.No)
{
return ResultadoDialogo.No;
}
else if(resultado == MessageBoxResult.None)
{
return ResultadoDialogo.None;
}
else if(resultado == MessageBoxResult.OK)
{
return ResultadoDialogo.OK;
}
else if(resultado == MessageBoxResult.Yes)
{
return ResultadoDialogo.Yes;
}
else
{
return ResultadoDialogo.Unknown;
}
}
}
And a class that use my method:
public class DialogoDummyMethods
{
//El método tiene que ser virtual para que moq pueda utilizarlo
public int getInt()
{
IDialogoDummy miGestor = new DialogoDummy();
ResultadoDialogo resultado = miGestor.dummy("OK es 0 y cancel es 1", "Test", MessageBoxButton.OKCancel, MessageBoxResult.Cancel);
int intResultado;
if (resultado == ResultadoDialogo.OK)
{
intResultado = 0;
}
else
{
intResultado = 1;
}
return intResultado;
}
}
And this is my Test:
[TestMethod]
public void DialogoTest01()
{
//La clase que se va a probar, que en este caso tiene también el método que se tiene que hacer mock, de modo.
Mock<IDialogoDummy> miDialogoDummyMock = new Mock<IDialogoDummy>();
//Se indica que cuando se llame al método dummy, con cualquier cadena tanto de mensaje como de caption, y con botones OKCancel y valor por
//defecto Canceal, devuelva 0.
miDialogoDummyMock.Setup(x => x.dummy(It.IsAny<string>(), It.IsAny<string>(), System.Windows.MessageBoxButton.OKCancel, System.Windows.MessageBoxResult.Cancel))
.Returns(GTS.CMMS.Client.Dialogos.ResultadoDialogo.OK);
DialogoDummyMethods misMetodos = new DialogoDummyMethods();
int intResultado = misMetodos.getInt();
Assert.AreEqual(0, intResultado, "Debería ser 0");
}
The problem is taht the mock object is different to the object that is created in the method that I want to test, so when the method to test is executed, the messageBox is shown and I have to select an option.
How can I test my getInt method without the needed to select an option in the dialog?
Thanks so much.
Upvotes: 1
Views: 99
Reputation: 236208
Your SUT (class which you are testing) should depend on abstractions only. Don't instantiate dependencies inside class - that introduces dependency on concrete class, which you cannot mock. Inject dependencies via constructor/property/parameter dependency injection. That will allow you to provide mocked dependency implementation.
So, all together:
1) Depend on abstraction
public class DialogoDummyMethods
{
private IDialogoDummy miGestor;
public int getInt()
{
// DialogoDummyMethods knows nothing about IDialogoDummy implementation
var resultado = miGestor.dummy(
"OK es 0 y cancel es 1", "Test",
MessageBoxButton.OKCancel, MessageBoxResult.Cancel);
return resultado == ResultadoDialogo.OK ? 0 : 1;
}
}
2) Inject abstraction through constructor. Note - if only one method needs IDialogoDummy, then you can inject it as method parameter (in that case you don't need IDialogDummy as class field)
public DialogoDummyMethods(IDialogoDummy miGestor)
{
this.miGestor = miGestor;
}
3) Mock dependency for unit-testing and inject mocked dependency to class which you are testing
var miDialogoDummyMock = new Mock<IDialogoDummy>();
// setup mock here
var misMetodos = new DialogoDummyMethods(miDialogoDummyMock.Object);
int intResultado = misMetodos.getInt();
Assert.AreEqual(0, intResultado, "Debería ser 0");
Upvotes: 1