Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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# Caliburn.微型单元测试_C#_Unit Testing_Caliburn.micro - Fatal编程技术网

C# Caliburn.微型单元测试

C# Caliburn.微型单元测试,c#,unit-testing,caliburn.micro,C#,Unit Testing,Caliburn.micro,我正在MVVM中完成我的第一步 我正在使用Caliburn.Micro作为我的MVVM框架 我有以下代码: using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Globalization; using Caliburn.Micro; namespace MY_PROJECT.ViewModels { [Export(typeof

我正在MVVM中完成我的第一步

我正在使用Caliburn.Micro作为我的MVVM框架

我有以下代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Globalization;

using Caliburn.Micro;

namespace MY_PROJECT.ViewModels
{   
    [Export(typeof(MainViewModel))]
    public class MainViewModel : Screen
    {     
        private readonly IWindowManager _windowManager = null;

        private readonly IEventAggregator _events;

        private string _title = string.Empty;          

        private WindowState _windowState = WindowState.Normal;

        public string Title
        {
            get
            {
               return _title;
            }
            set
            {
               _title = value;
               NotifyOfPropertyChange(() => Title);
            }
        }

        public WindowState WindowState
        {
            get
            {
                return _windowState;
            }
            set
            {
                _windowState = value;
                NotifyOfPropertyChange(() => WindowState);
            }
        }

        public void ChangeTittle(string title)
        {
             Title = title;
        }

        public void ToggleWindowState()
        {
             WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
        }

        [ImportingConstructor]
        public MainViewModel(IWindowManager windowManager, IEventAggregator events)
        {
            _windowManager = windowManager;
            _events = events;
            _events.Subscribe(this);
        }
  }
现在我想编写一些简单的单元测试来测试我的viewmodel

有什么建议吗


Caliburn.Micro的文档似乎缺少这些信息。

好的,您可以通过IoC容器运行整个应用程序并引导整个过程,这样您就可以获得所有接口的实际具体实现。这样做的缺点是,您将需要所有可用的东西(数据库、web服务等),如果您非常需要应用程序全部运行,那么测试应用程序可能会更加困难(而且由于实际工作正在完成,执行测试可能会慢得多)。如果你能很容易地走这条路,那么一定要使用它

或者,您可以使用mock或stub,通过使用Moq之类的模拟框架来模拟对象的行为/状态

使用Moq,您可以设置测试环境,以便您的接口和类由指定行为的
Mock
(Mock对象)表示。然后在
ViewModels

下面是一组使用Moq和NUnit对当前版本中的
MainViewModel
进行测试的示例:

// Decorate with test fixture attribute so NUnit knows it's a test
[TestFixture]
class MainViewModelTests
{           
    // The interfaces/instances you will need to test with - this is your test subject
    MainViewModel _mainVM;

    // You can mock the other interfaces:
    Mock<IWindowManager> _windowManager;
    Mock<IEventAggregator> _eventAggregator; 

    // Setup method will run at the start of each test
    [SetUp]
    public void Setup() 
    {
        // Mock the window manager
        _windowManager = new Mock<IWindowManager>();               

        // Mock the event aggregator
        _windowManager = new Mock<IEventAggregator>(); 

        // Create the main VM injecting the mocked interfaces
        // Mocking interfaces is always good as there is a lot of freedom
        // Use mock.Object to get hold of the object, the mock is just a proxy that decorates the original object
        _mainVM = new MainViewModel(_windowManager.Object, _eventAggregator.Object);
    }

    // Create a test to make sure the VM subscribes to the aggregator (a GOOD test, I forget to do this a LOT and this test gives me a slap in the face)
    [Test]
    public void Test_SubscribedToEventAggregator()
    {
        // Test to make sure subscribe was called on the event aggregator at least once
        _eventAggregator.Verify(x => x.Subscribe(_mainVM));
    }

    // Check that window state toggles ok when it's called
    [Test]
    public void Test_WindowStateTogglesCorrectly()
    {
        // Run the aggregator test at the start of each test (this will run as a 'child' test)
        Test_SubscribedToEventAggregator();

        // Check the default state of the window is Normal
        Assert.True(_mainVM.WindowState == WindowState.Normal);

        // Toggle it
        _mainVM.ToggleWindowState();

        // Check it's maximised
        Assert.True(_mainVM.WindowState == WindowState.Maximised);

        // Check toggle again for normal
        _mainVM.ToggleWindowState();

        Assert.True(_mainVM.WindowState == WindowState.Normal);
    }

    // Test the title changes correctly when the method is called
    [Test]
    public void Test_WindowTitleChanges()
    {
         Test_SubscribedToEventAggregator();

         _mainVM.ChangeTitle("test title");
         Assert.True(_mainVM.Title == "test title");
    }
}
在此处查看Moq快速入门:


单元测试不在Caliburn.Micro的范围内,因为该框架是MVVM框架,而不是单元测试框架。它允许您轻松地进行单元测试,它不提供任何类型的单元测试接口。你可能想在谷歌上快速搜索一下。我可以向您介绍一些流行的测试框架——NUnit非常流行,并且有很多教程,MSTest是微软提供的集成到Visual Studio中的产品之一。我知道Caliburn.Micro不是一个单元测试框架。我的计划实际上是使用xUnit作为单元测试框架。但是,我不明白创建测试的过程是什么。例如,我需要做的第一件事是初始化视图模型。但是我如何提供windowManager和构造函数所需的事件呢?我也需要初始化引导程序吗?这些是我没有得到的东西。您可以在测试设置方法中实际提供这些实例,或者使用mock来模拟所需接口或类型的状态或行为。看看Moq或者其他一些模仿InfoQ的框架,等我不在手机上的时候,我会发布一些例子!非常感谢!实际上,我把NSubstitute看作是一个模拟库,但moq似乎也在做这项工作。Charleh,即使在模拟环境中,单元测试仍然需要加载Caliburn.Micro-assembly才能访问IEventAggregator接口。加载该程序集可能会给单元测试框架带来很大的负担吗?我只是意识到测试应该是轻量级和快速的。对这条评论的回应有点晚了,但不,你的应用程序可能会比CM大得多。首先,框架非常小。我的测试运行得很快——用具体的实现引导整个应用程序从来都不是一个好主意。尤其是当您访问实时数据时。您应该测试ViewModel与其依赖项之间的交互。您不应该测试ViewModel是否可以一直访问数据库。对于这样的测试,只针对数据库代码编写一个单元测试,然后从那里开始。
public class MainViewModel : IHandle<someEventMessageArgument> // (this is your subscriber interface)
{ 
    // (and this is the corresponding method)
    public void Handle(someEventMessageArgument message) 
    { 
        // do something useful maybe change object state or call some methods
    }
}

// Test the method - you don't need to mock any event aggregator behaviour since you have tested that the VM was subscribed to the aggregator. (OK CM might be broken but that's Robs problem :))
[Test]
Test_SomeEventDoesWhatYouAreExpecting()
{
    _mainVM.Handle(someEventMessageArgument);

    // Assert that what was supposed to happen happened...
    Assert.True(SomethingHappened);
}