我的基类中有以下受保护的方法:
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的原因。我怎么能这样做(用moq)?
答案 0 :(得分:3)
您只需要对MessageBox
个动作进行界面操作,以便在始终返回MockMessageBox
的单元测试时提供MessageBoxResult.Yes
。因此,在您的代码中,不要直接引用任何MessageBox
es。创建一个您调用的WindowManager
或MessageBoxService
类,有点像代理消息框。
例如,尝试这样的事情:
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;
}
答案 1 :(得分:0)
我真的建议你遵循@Sheridan解释的概念;但是如果你想按照自己的方式行事,这里是如何模拟受保护方法的解决方案:
Mock<YourBaseClass> baseClassMock = new Mock<YourBaseClass>();
baseClassMock.Protected().Setup<bool>(
"ExecuteInteraction",
ItExpr.IsAny<string>(),
ItExpr.IsAny<Action<object>>(),
ItExpr.IsAny<object[]>())
.Returns(true);