简体   繁体   English

模拟使用Moq使用可选参数的方法

[英]Mocking a Method that uses an Optional Parameter using Moq

I have a message box service that hase the following interface 我有一个消息框服务,其中包含以下界面

public interface IMessageBoxService
{
    DialogResult DisplayMessage(IWin32Window owner, string text,
        string caption, MessageBoxButtons buttons, MessageBoxIcon icon,
        MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1);
}

It essentally wraps the System.Windows.Forms message box and allows me to Mock parts of my code that show a message box. 它只是包装了System.Windows.Forms消息框,并允许我模拟显示消息框的部分代码。 Now I have a search service for text documents that shows a "No more occurrances located" message if the search looped. 现在,我有一个文本文档的搜索服务,如果搜索循环,则显示“不再有位于”的消息。 I want to write a unit test for the functionality of this class, the FindNextMethod is 我想为这个类的功能编写单元测试, 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;
        }
    }
    ...
}

My test is 我的考试是

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

However I am getting an 但是我得到了一个

System.Reflection.TargetParameterCountException Parameter count mismatch. System.Reflection.TargetParameterCountException参数计数不匹配。

I have seen this question and I seem to be doing as the answer suggest and supplying the optional parameter but I still get the exception, why? 我已经看到了这个问题 ,我似乎正在做的答案建议并提供可选参数,但我仍然得到例外,为什么?

I have seen an answer here suggesting I have to use .Result with the correct parameter count, so I tried 我在这里看到一个答案,建议我必须使用.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++;
            });

Thanks for your time. 谢谢你的时间。

The TargetParameterCountException is thrown because your callback registration is only registered with one parameter. 抛出TargetParameterCountException,因为您的回调注册仅使用一个参数注册。

.Callback<DialogResult>(r =>
        {
            Trace.WriteLine($"MockMessageBoxService {r.ToString()}");
            dialogShownCounter++;
        });

The Callback cannot accept the value returned by Returns. Callback不能接受Returns返回的值。 It still has to match the mocked method signature. 它仍然必须匹配模拟的方法签名。

.Callback((IWin32Window a1, string a2,
    string a3, MessageBoxButtons a4, MessageBoxIcon a5,
    MessageBoxDefaultButton a6) => { dialogShownCounter++ });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM