模拟受保护的方法总是返回 true

本文关键字:返回 true 方法 受保护 模拟 | 更新日期: 2023-09-27 18:35:03

我的基类中有以下受保护的方法:

protected bool ExecuteInteraction(string identifier,
    Action<object> interactionFinished, params object[] args)
{
    Contract.Requires(!string.IsNullOrEmpty(identifier));
    Contract.Requires(interactionFinished != null);
    bool result = false;
    if (!string.IsNullOrEmpty(identifier) && (interactionFinished != null))
    {
        // Find the matching interaction behavior.
        IInteractionBehavior interactionBehavior =
            InteractionBehaviorCollection.Instance.Get(identifier);
        if (interactionBehavior != null)
        {
            try
            {
                interactionBehavior.Execute(interactionFinished, args);
                result = true;
            }
            catch (Exception)
            {
            }
        }
        else
        {
            Debug.WriteLine(string.Format(
                "InteractionBehavior with identifier [{0}] is unknown",
                identifier));
        }
    }
    return result;
}

它基本上来自这篇文章:http://www.codeproject.com/Articles/708346/Dialogs-the-MVVM-Way...

此方法在我的派生类中使用,如下所示:

protected override void Delete()
{
    try
    {
        if (PrimaryModel.Id != 0 && PrimaryModel.AddressId != 0)
        {
            ExecuteInteraction("DeleteConfirmation", (result) =>
            {
                MessageBoxResult messageBoxResult = (MessageBoxResult)result;
                if (messageBoxResult == MessageBoxResult.Yes)
                {
                    //Do something ...
                }
            });
        }
    }
    catch (Exception exc)
    {
        Message = exc.Message;
    }
}

这在我的单元测试中不起作用,因为我不模拟 messageBoxResult 是 MessageBoxResult.Yes。这就是为什么我希望我的受保护方法在单元测试中始终返回 true 的原因。我该怎么做(最小起订量(?

模拟受保护的方法总是返回 true

您只需要对MessageBox操作进行接口,以便在单元测试时提供始终返回MessageBoxResult.Yes MockMessageBox。因此,在您的代码中,不要直接引用任何 MessageBox es。创建一个WindowManagerMessageBoxService类,改为调用,有点像代理消息框。

例如,尝试如下操作:

public string ShowMessageBox(string message, string title, string buttons, string icon)
{
    MessageBoxButton messageBoxButtons;
    switch (buttons.ToLower())
    {
        case "ok": messageBoxButtons = MessageBoxButton.OK; break;
        case "okcancel": messageBoxButtons = MessageBoxButton.OKCancel; break;
        case "yesno": messageBoxButtons = MessageBoxButton.YesNo; break;
        case "yesnocancel": messageBoxButtons = MessageBoxButton.YesNoCancel; break;
        default: messageBoxButtons = MessageBoxButton.OKCancel; break;
    }
    MessageBoxImage messageBoxImage;
    switch (icon.ToLower())
    {
        case "asterisk": messageBoxImage = MessageBoxImage.Asterisk; break;
        case "error": messageBoxImage = MessageBoxImage.Error; break;
        case "exclamation": messageBoxImage = MessageBoxImage.Exclamation; break;
        case "hand": messageBoxImage = MessageBoxImage.Hand; break;
        case "information": messageBoxImage = MessageBoxImage.Information; break;
        case "none": messageBoxImage = MessageBoxImage.None; break;
        case "question": messageBoxImage = MessageBoxImage.Question; break;
        case "stop": messageBoxImage = MessageBoxImage.Stop; break;
        case "warning": messageBoxImage = MessageBoxImage.Warning; break;
        default: messageBoxImage = MessageBoxImage.Stop; break;
    }
    return MessageBox.Show(message, title, messageBoxButtons, messageBoxImage).ToString();
}

这将被称为:

string result = WindowManager.ShowMessageBox(message, title, "OkCancel", "Question");

请注意,与任何 UI dll 都没有直接关系...所有属性都是基于字符串的。现在你需要接口此方法所在的类 ( WindowManager (。所以现在我们有一个IWindowManager,迫使我们在所有实现类中编写一个ShowMessageBox方法。

现在我们在MockWindowManager类中实现此接口:

public string ShowMessageBox(string message, string title, string buttons, string icon)
{
    switch (buttons)
    {
        case "Ok":
        case "OkCancel": return "OK";
        case "YesNo":
        case "YesNoCancel": return "Yes";
        default: return "OK";
    }
}

运行应用程序时,我们使用 WindowManager 类,在测试时,我们使用 MockWindowManager 类。这可以通过多种方式实现,但最简单的方法是将IWindowManager传递到视图模型构造函数中:

public YourViewModel(IWindowManager windowManager)
{
    this.windowManager = windowManager;
}

我真的建议你遵循@Sheridan解释的概念;但如果你想走自己的路,这里是如何模拟受保护方法的解决方案:

Mock<YourBaseClass> baseClassMock = new Mock<YourBaseClass>();
baseClassMock.Protected().Setup<bool>(
    "ExecuteInteraction", 
     ItExpr.IsAny<string>(),
     ItExpr.IsAny<Action<object>>(),
     ItExpr.IsAny<object[]>())
.Returns(true);