Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以下设置不匹配,WPF MVVM使用Moq进行单元测试_C#_Wpf_Unit Testing_Mvvm_Moq - Fatal编程技术网

C# 以下设置不匹配,WPF MVVM使用Moq进行单元测试

C# 以下设置不匹配,WPF MVVM使用Moq进行单元测试,c#,wpf,unit-testing,mvvm,moq,C#,Wpf,Unit Testing,Mvvm,Moq,我正在用Moq在WPF中编写一个单元测试,测试用户在关闭窗口时是否单击了YesNoCancel消息框上的“是”按钮。在我的CloseCommand视图中,当用户关闭窗口时,Model会给出以下消息: var result = _messageSvc.Show( "Do you want to save changes?", "Save Changes", Services.MessageBoxButton.YesNoCancel, Services.Messag

我正在用MoqWPF中编写一个单元测试,测试用户在关闭窗口时是否单击了
YesNoCancel
消息框上的“是”按钮。在我的
CloseCommand
视图中,当用户关闭窗口时,Model会给出以下消息:

var result = _messageSvc.Show(
    "Do you want to save changes?",
    "Save Changes", 
    Services.MessageBoxButton.YesNoCancel,
    Services.MessageBoxIcon.Question, 
    Services.MessageBoxResult.Yes);
My
\u messageSvc
是自定义消息服务中的一个私有实例,用于显示消息框。以下是该服务的代码:

public interface IMessageSvc
{
    void Show(string message);
    MessageBoxResult Show(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon, MessageBoxResult defaultResult = 0);
}

public class MessageSvc : IMessageSvc
{
    public void Show(string message)
    {
        MessageBox.Show(message);
    }

    public MessageBoxResult Show(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon, MessageBoxResult defaultResult)
    {
        return (MessageBoxResult)MessageBox.Show(message, caption, (System.Windows.MessageBoxButton)buttons, (System.Windows.MessageBoxImage)icon, (System.Windows.MessageBoxResult)defaultResult);
    }
}
注意:
MessageBoxButton
MessageBoxIcon
MessageBoxResult
是我在同一个文件中进行的枚举,以模拟.NET提供的现成功能。为了便于阅读,我不在这里展示它们

我的单元测试是:

[TestMethod]
public void ShouldAskToSaveOnCloseRespondYesTest()
{
    // Mock and setup initial user data 
    var u= new User
    {
        UserId = 1,
        UserName = "FirstName LastName",
        FavoriteColor = "Blue"
    };
    mainViewModel.UserInfo= new UserInfoDtoWrapper(u);

    // assert the data has not changed yet
    Assert.IsFalse(mainViewModel.UserInfo.IsChanged);

    // change the user data
    mainViewModel.UserInfo.UserName= "LastName FirstName";

    // assert the data has changed
    Assert.IsTrue(mainViewModel.UserInfo.IsChanged);

    // execute window closing
    mainViewModel.CloseCommand.Execute(new object());

    // verify messagebox shows and the 'Yes' button is clicked
    // this will then save the changes made to the user instance
    var messageBox = new Mock<IMessageSvc>();
    messageBox.Setup(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
        It.Is<string>(y => y == "Save Changes"),
        It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
        It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
        It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)))
        .Returns(MessageBoxResult.Yes);

    messageBox.Verify();
}
[TestMethod]

public void应要求使用osaveoncloserespondentyestest()命令 { //模拟和设置初始用户数据 var u=新用户 { UserId=1, UserName=“FirstName LastName”, FavoriteColor=“蓝色” }; mainViewModel.UserInfo=新的UserInfoDtoWrapper(u); //断言数据尚未更改 Assert.IsFalse(mainViewModel.UserInfo.IsChanged); //更改用户数据 mainViewModel.UserInfo.UserName=“LastName FirstName”; //断言数据已更改 IsTrue(mainViewModel.UserInfo.IsChanged); //执行窗口关闭 mainViewModel.CloseCommand.Execute(新对象()); //验证messagebox是否显示并单击“是”按钮 //然后,这将保存对用户实例所做的更改 var messageBox=new Mock(); messageBox.Setup(x=>x.Show(It.Is(y=>y==“是否保存更改?”), 它是(y=>y==“保存更改”), 它是(y=>y==MessageBoxButton.YesNoCancel), 它是(y=>y==MessageBoxIcon.Question), 它是(y=>y==MessageBoxResult.Yes))) .Returns(MessageBoxResult.Yes); messageBox.Verify(); }
错误出现在
messageBox.Verify()
行上,但从我所看到的情况来看,我做的是正确的。我需要获取messagebox的返回值,以继续测试用户单击“是”按钮后发生的情况,因此我不想在内部使用带有Linq查询的
Verify
,而是需要捕获结果


谢谢

这行不通。测试代码中有两个问题:

  • 首先启动
    CloseCommand
    (假定该命令调用
    IMessageSvc.Show
    方法),然后才为该服务设置模拟

  • 您为服务设置了一个新的模拟,但没有使用它

  • 要更正这些错误,请执行以下操作:

    • 更改顺序,使其成为正确的“排列”-“动作”-“断言”顺序
    • 使用依赖项注入在视图模型中注入模拟服务
    以下是一个例子:

    class MainViewModel
    {
        private readonly IMessageSvc _messageSvc;
    
        public MainViewModel(IMessageSvc svc)
        {
            this._messageSvc = svc;
        }
    }
    
    [TestMethod]
    public void ShouldAskToSaveOnCloseRespondYesTest()
    {
        // Arrange
        var messageBox = new Mock<IMessageSvc>();
        messageBox.Setup(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
            It.Is<string>(y => y == "Save Changes"),
            It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
            It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
            It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)))
            .Returns(MessageBoxResult.Yes)
            .Verifiable();
    
        var mainViewModel = new MainViewModel(messageBox.Object);
    
        // Act
        mainViewModel.CloseCommand.Execute(new object());
    
        // Assert
        messageBox.Verify();
    }
    
    class主视图模型
    {
    私有只读IMessageSvc _messageSvc;
    公共主视图模型(IMessageSvc svc)
    {
    这个。_messageSvc=svc;
    }
    }
    [测试方法]
    
    public void应要求使用osaveoncloserespondentyestest()命令 { //安排 var messageBox=new Mock(); messageBox.Setup(x=>x.Show(It.Is(y=>y==“是否保存更改?”), 它是(y=>y==“保存更改”), 它是(y=>y==MessageBoxButton.YesNoCancel), 它是(y=>y==MessageBoxIcon.Question), 它是(y=>y==MessageBoxResult.Yes))) .Returns(MessageBoxResult.Yes) .可验证(); var mainViewModel=新的mainViewModel(messageBox.Object); //表演 mainViewModel.CloseCommand.Execute(新对象()); //断言 messageBox.Verify(); }
    当前,您正在测试调用模拟方法的代码后设置模拟方法。将您的测试重新安排为如下模式:

    var messageBox = new Mock<IMessageSvc>();
    messageBox.Setup(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
        It.Is<string>(y => y == "Save Changes"),
        It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
        It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
        It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)))
        .Returns(MessageBoxResult.Yes);
    
    mainViewModel.CloseCommand.Execute(new object());
    
    messageBox.Verify(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
        It.Is<string>(y => y == "Save Changes"),
        It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
        It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
        It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)));
    
    var messageBox=new Mock();
    messageBox.Setup(x=>x.Show(It.Is(y=>y==“是否保存更改?”),
    它是(y=>y==“保存更改”),
    它是(y=>y==MessageBoxButton.YesNoCancel),
    它是(y=>y==MessageBoxIcon.Question),
    它是(y=>y==MessageBoxResult.Yes)))
    .Returns(MessageBoxResult.Yes);
    mainViewModel.CloseCommand.Execute(新对象());
    验证(x=>x.Show(It.Is(y=>y==“是否保存更改?”),
    它是(y=>y==“保存更改”),
    它是(y=>y==MessageBoxButton.YesNoCancel),
    它是(y=>y==MessageBoxIcon.Question),
    它是(y=>y==MessageBoxResult.Yes));
    
    “错误出现在messageBox.Verify()行”-什么错误?ShouldAsktosaveonCloseRespondeYesTest引发异常:Moq.MockVerificationException:以下设置不匹配:IMessageSvc x=>x.Show(It.Is(y=>y==“是否保存更改?”),It.Is(y=>y==“保存更改”)…安装和验证之间的其余代码在哪里?目前没有执行任何测试。我想这就是我的问题所在。我需要验证messagebox是否显示。然后我是否应该调用“messagebox.Show”或者显示我在上面创建的messageBox对象?我以前尝试过这个,在这种情况下返回的错误是
    预期对模拟调用一次,但使用
    messageBox.Verify(x=>x.show(It.is(y=>y==“是否保存更改?”),It.is(y=>y==“保存更改”),It.Is(y=>y==MessageBoxButton.YesNoCancel),It.Is(y=>y==MessageBoxIcon.Question),It.Is(y=>y==MessageBoxResult.Yes)),Times.Once);
    我将我的IMessageService注入到ViewModel中并在单元测试类中初始化,所以当我运行
    \u messageSvc.Verify时(x=>x.Show(It.Is(y=>y==“是否保存更改?”)、It.Is(y=>y==“保存更改”)、It.Is(y=>y==MessageBoxButton.YesNoCancel)、It.Is(y=>y==MessageBoxIcon.Question)、It.Is(y=>y==MessageBoxResult.Yes))、次)
    它可以工作,但我需要设置messagebox以获取t