使用 Moq 模拟使用可选参数的方法
Mocking a Method that uses an Optional Parameter using Moq
我有一个具有以下界面的消息框服务
public interface IMessageBoxService
{
DialogResult DisplayMessage(IWin32Window owner, string text,
string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1);
}
它基本上包装了 System.Windows.Forms
消息框,并允许我模拟显示消息框的代码部分。现在我有一个文本文档搜索服务,如果搜索循环,它会显示 "No more occurrances located" 消息。我想为这个 class 的功能写一个单元测试, FindNextMethod
是
public TextRange FindNext(IDocumentManager documentManager, IMessageBoxService messageBoxService,
TextEditorControl textEditor, SearchOptions options, FindAllResultSet findAllResults = null)
{
...
if (options.SearchType == SearchType.CurrentDocument)
{
Helpers.SelectResult(textEditor, range);
if (persistLastSearchLooped)
{
string message = MessageStrings.TextEditor_NoMoreOccurrances;
messageBoxService.DisplayMessage(textEditor.Parent, message,
Constants.Trademark, MessageBoxButtons.OK, MessageBoxIcon.Information); <- Throws here.
Log.Trace($"TextEditorSearchProvider.FindNext(): {message}");
lastSearchLooped = false;
}
}
...
}
我的测试是
[TestMethod]
public void FindInCurrentForwards()
{
// Mock the IMessageBoxService.
int dialogShownCounter = 0;
var mock = new Mock<IMessageBoxService>();
mock.Setup(m => m.DisplayMessage(It.IsAny<IWin32Window>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<MessageBoxButtons>(), It.IsAny<MessageBoxIcon>(), It.IsAny<MessageBoxDefaultButton>()))
.Returns(DialogResult.OK)
.Callback<DialogResult>(r =>
{
Trace.WriteLine($"MockMessageBoxService {r.ToString()}");
dialogShownCounter++;
});
// Start the forward search through the first document.
var options = new SearchOptions()
{
SearchText = "SomeText",
SearchType = SearchType.CurrentDocument,
MatchCase = false,
MatchWholeWord = false,
SearchForwards = false
};
var searchProvider = new TextEditorSearchProvider();
var textEditor = ((TextEditorView)documentManager.GetActiveDocument().View).TextEditor;
TextRange range = null;
for (int i = 0; i < occurances + 1; ++i)
range = searchProvider.FindNext(documentManager, mock.Object, textEditor, options);
// We expect the text to be found and the dialog to be displayed once.
Assert.IsNotNull(range);
Assert.AreEqual(1, dialogShownCounter);
}
但是我得到了一个
System.Reflection.TargetParameterCountException Parameter count mismatch.
我已经看到了这个 question 我似乎按照答案的建议做了并提供了可选参数,但我仍然遇到异常,为什么?
我看到 answer here 建议我必须使用具有正确参数计数的 .Result
,所以我尝试了
mock.Setup(m => m.DisplayMessage(It.IsAny<IWin32Window>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<MessageBoxButtons>(), It.IsAny<MessageBoxIcon>(), It.IsAny<MessageBoxDefaultButton>()))
.Returns((IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton) => DialogResult.OK)
.Callback<DialogResult>(r =>
{
Trace.WriteLine($"MockMessageBoxService {r.ToString()}");
dialogShownCounter++;
});
感谢您的宝贵时间。
因为你的回调注册只注册了一个参数,所以抛出TargetParameterCountException
.Callback<DialogResult>(r =>
{
Trace.WriteLine($"MockMessageBoxService {r.ToString()}");
dialogShownCounter++;
});
回调无法接受 Returns 返回的值。它仍然必须匹配模拟方法签名。
.Callback((IWin32Window a1, string a2,
string a3, MessageBoxButtons a4, MessageBoxIcon a5,
MessageBoxDefaultButton a6) => { dialogShownCounter++ });
我有一个具有以下界面的消息框服务
public interface IMessageBoxService
{
DialogResult DisplayMessage(IWin32Window owner, string text,
string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1);
}
它基本上包装了 System.Windows.Forms
消息框,并允许我模拟显示消息框的代码部分。现在我有一个文本文档搜索服务,如果搜索循环,它会显示 "No more occurrances located" 消息。我想为这个 class 的功能写一个单元测试, FindNextMethod
是
public TextRange FindNext(IDocumentManager documentManager, IMessageBoxService messageBoxService,
TextEditorControl textEditor, SearchOptions options, FindAllResultSet findAllResults = null)
{
...
if (options.SearchType == SearchType.CurrentDocument)
{
Helpers.SelectResult(textEditor, range);
if (persistLastSearchLooped)
{
string message = MessageStrings.TextEditor_NoMoreOccurrances;
messageBoxService.DisplayMessage(textEditor.Parent, message,
Constants.Trademark, MessageBoxButtons.OK, MessageBoxIcon.Information); <- Throws here.
Log.Trace($"TextEditorSearchProvider.FindNext(): {message}");
lastSearchLooped = false;
}
}
...
}
我的测试是
[TestMethod]
public void FindInCurrentForwards()
{
// Mock the IMessageBoxService.
int dialogShownCounter = 0;
var mock = new Mock<IMessageBoxService>();
mock.Setup(m => m.DisplayMessage(It.IsAny<IWin32Window>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<MessageBoxButtons>(), It.IsAny<MessageBoxIcon>(), It.IsAny<MessageBoxDefaultButton>()))
.Returns(DialogResult.OK)
.Callback<DialogResult>(r =>
{
Trace.WriteLine($"MockMessageBoxService {r.ToString()}");
dialogShownCounter++;
});
// Start the forward search through the first document.
var options = new SearchOptions()
{
SearchText = "SomeText",
SearchType = SearchType.CurrentDocument,
MatchCase = false,
MatchWholeWord = false,
SearchForwards = false
};
var searchProvider = new TextEditorSearchProvider();
var textEditor = ((TextEditorView)documentManager.GetActiveDocument().View).TextEditor;
TextRange range = null;
for (int i = 0; i < occurances + 1; ++i)
range = searchProvider.FindNext(documentManager, mock.Object, textEditor, options);
// We expect the text to be found and the dialog to be displayed once.
Assert.IsNotNull(range);
Assert.AreEqual(1, dialogShownCounter);
}
但是我得到了一个
System.Reflection.TargetParameterCountException Parameter count mismatch.
我已经看到了这个 question 我似乎按照答案的建议做了并提供了可选参数,但我仍然遇到异常,为什么?
我看到 answer here 建议我必须使用具有正确参数计数的 .Result
,所以我尝试了
mock.Setup(m => m.DisplayMessage(It.IsAny<IWin32Window>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<MessageBoxButtons>(), It.IsAny<MessageBoxIcon>(), It.IsAny<MessageBoxDefaultButton>()))
.Returns((IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton) => DialogResult.OK)
.Callback<DialogResult>(r =>
{
Trace.WriteLine($"MockMessageBoxService {r.ToString()}");
dialogShownCounter++;
});
感谢您的宝贵时间。
因为你的回调注册只注册了一个参数,所以抛出TargetParameterCountException
.Callback<DialogResult>(r =>
{
Trace.WriteLine($"MockMessageBoxService {r.ToString()}");
dialogShownCounter++;
});
回调无法接受 Returns 返回的值。它仍然必须匹配模拟方法签名。
.Callback((IWin32Window a1, string a2,
string a3, MessageBoxButtons a4, MessageBoxIcon a5,
MessageBoxDefaultButton a6) => { dialogShownCounter++ });