如何模拟测试方法中使用的对象?

时间:2014-08-08 15:33:36

标签: unit-testing dialog modal-dialog moq

我正在做一些测试,以了解如何模拟使用对话框的方法。我有这个课程:

我的界面,这是MessageBox的包装。

public interface IDialogoDummy
    {
        ResultadoDialogo dummy(string paramMensaje, string paramCaption, System.Windows.MessageBoxButton paramBotones, MessageBoxResult paramBotonPorDefecto);
    }

实现我的界面的类:

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;
            }
        }
    }

使用我的方法的类:

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;
        }
    }

这是我的测试:

[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");
        }

问题是模拟对象与我想要测试的方法中创建的对象不同,因此当执行测试方法时,会显示messageBox,我必须选择一个选项。

如何在不需要在对话框中选择选项的情况下测试我的getInt方法?

非常感谢。

1 个答案:

答案 0 :(得分:1)

您的SUT(您正在测试的课程)应仅依赖于抽象。不要在类中实例化依赖关系 - 这会引入对具体类的依赖,这是您无法模拟的。通过构造函数/属性/参数依赖注入注入依赖项。这将允许您提供模拟的依赖项实现。

所以,一起:

1)取决于抽象

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)通过构造函数注入抽象。注意 - 如果只有一个方法需要IDialogoDummy,那么你可以将它作为方法参数注入(在这种情况下你不需要IDialogDummy作为类字段)

public DialogoDummyMethods(IDialogoDummy miGestor)
{
    this.miGestor = miGestor;
}

3)对单元测试进行模拟依赖,并将模拟依赖注入正在测试的类

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");