Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.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# 使用Moq和MVP-VM进行单元测试_C#_Wpf_Unit Testing_Moq - Fatal编程技术网

C# 使用Moq和MVP-VM进行单元测试

C# 使用Moq和MVP-VM进行单元测试,c#,wpf,unit-testing,moq,C#,Wpf,Unit Testing,Moq,我正在尝试使用MVP-VM模式在代码中执行单元测试(使用Moq的集成测试)。我有一个视图、一个视图模型和一个演示者 演示者拥有我的UI的实际功能 我试图测试演示者的方式如下 public interface IMockView : IRealView { event EventHandler ButtonClickedEvent; } public interface IMockViewModel : IRealViewModel { } public class Mo

我正在尝试使用MVP-VM模式在代码中执行单元测试(使用Moq的集成测试)。我有一个视图、一个视图模型和一个演示者

演示者拥有我的UI的实际功能

我试图测试演示者的方式如下

public interface IMockView : IRealView
{
        event EventHandler ButtonClickedEvent;
}

public interface IMockViewModel :  IRealViewModel 
{  }

public class MockPresenter  :  RealPresenter 
{
    private IMockView _view;
    private IMockViewModel _viewModel;
    public MyProperty { get; set; }

    public MockPresenter  (IMockView  view, IMockViewModel  viewModel) 
        :base(view, viewModel)
    {
        _view = view;
        _viewModel = viewModel;

        view.ButtonClickedEvent += (s, e) =>
                               {
                                     //Do Something 
                                     this.MyProperty = Property retrieved from db.     
                               };
    }
}
这是我的测试代码。(我使用NUnit测试框架和Moq)

[测试]
public void TriggerCreateClicked()
{
var view=newmock();
var viewModel=new Mock();
var presenter=新的MockPresenter(view.Object、viewModel.Object);
viewModel.Setup(x=>x.IsValid)。返回(true)
.Raises(t=>t.ButtonClickedEvent+=null,EventArgs.Empty);
viewModel.Object.IsValid=true;
Assert.NotNull(presenter.MyProperty);
}
基本上,在我的测试用例中

如果ViewModel.IsValid返回true,我将提升按钮ClickedEvent。 然后,在Presenter内部,我想从db中检索一些属性并将其存储在MyProperty中。然后,我想测试这个MyProperty是否为Null。如果测试无一例外地顺利通过,那么具有MyProperty的演示者应该保存一些值


我的问题是,为了执行模拟测试,创建继承RealPresenter(类)的MockPresenter(而不是接口)是否合适?由于我在RealPresenter中的代码不提供任何getter或setter来检索此属性,因此我决定通过MockPresenter类继承RealPresenter,以免影响我的RealPresenter。我还没有在网上看到任何使我的方法可行的示例代码

第一个问题是,在测试方法中,您是否只测试了一件事情。在您的例子中,我认为您在一个方法中测试了两件事:当验证返回true时引发事件,以及在处理事件时检索数据。我建议你把它们分成两种测试方法

第二个问题是使用Mock而不进行验证,这意味着测试方法中的所有Mock都是存根。我想在你的方法中至少你会验证一个

第三个问题是,我没有得到您真正的逻辑,因为您在模拟接口和测试方法中添加了一些额外的逻辑


我认为在使用MVVM对WPF进行单元测试时,您可能不必测试引发事件处理程序,因为这是.Net framework的工作。您需要测试的是事件处理程序是否正常工作。如果通过命令绑定,您可以模拟命令来测试调用,如果命令的实现包含依赖项,例如数据库连接。

您好,比尔,谢谢您的回答。对于您的问题,我只测试一件事,即当用户单击视图上的“按钮”时,演示者将引发创建表的事件并将其插入数据库。这就是我在MockPresenter上引发此事件的原因。我将通过MockPresenter继承RealPresenter的原因是RealPresenter中的testmethod包含一些我不需要测试的其他内容。因此,我所做的是创建了MockPresenter,其中包含唯一可测试的部分(基本上是从RealPresenter复制和粘贴)。一旦我通过用户单击按钮在我的测试方法上创建了这个表,我将引发事件并从db中检索我创建的表,并检查是否正确检索了这个表。对于第二个问题,我想你的意思是,我会说,view.verify(…)或viewModel.verify(…)这就是你的意思吗?对于第三个问题,在我的视图或viewModel界面上,没有其他逻辑。您能告诉我我选择的方式是否适合测试吗?因此真正的逻辑是用户单击视图上的按钮,Presenter处理单击事件处理程序,Presenter在视图上创建一个表,完成后检索数据。由于创建表是不可测试的,所以您可以在模拟视图中创建一个事件,而不必在模拟演示者的事件处理程序中创建表。我说得对吗?
    [Test]
    public void TriggerCreateClicked()
    {
        var view = new Mock<IMockView>();
        var viewModel = new Mock<IMockViewModel>();
        var presenter = new MockPresenter(view.Object,   viewModel.Object);

        viewModel.Setup(x => x.IsValid).Returns(true)
                 .Raises(t => t.ButtonClickedEvent += null, EventArgs.Empty);

        viewModel.Object.IsValid = true;

        Assert.NotNull(presenter.MyProperty);
    }