简体   繁体   English

测试异步/回调Visual Studio

[英]Testing Asynchronous/Callbacks Visual Studio

I need to write some tests for a whole bunch of C# code similar to the below example. 我需要为一大堆C#代码编写一些测试,类似于下面的示例。 This is one of my first tasks in C# and I've been unlucky enough to get dumped straight into async code :(. Its a web application that makes a bunch of database requests: 这是我在C#中执行的第一个任务,但不幸的是,我无法直接将其转储到异步代码中:(。它是一个Web应用程序,可以发出大量数据库请求:

namespace Foo.ViewModel
{
    public class FooViewModel
    {
        private ManagementService _managementService;
        public int Status { get; set; }
        public Foo()
        {
            Status = 5;
            _managementService = new ManagementService();
            _managementService.GetCustomerInfoCompleted += new EventHandler<GetCustomerInfoEventArgs>(CustomerInfoCallback);

        }

        public void GetCustomerInfo(int count)
        {
            int b;
            if (someCondition() || otherCondition())
            {
                b = 2;
            }
            else
            {
                b = SomeOtherAsynchronousMethod();
            }
            _managementService.GetCustomerInfoAsync(b, count);
            //when completed will call CustomerInfoCallback
        }

        void CustomerInfoCallback(object sender, GetCustomerInfoEventArgs args)
        {
            Status = args.Result.Result.Total;
            UpdateView();
        }

    }

}

I'd like to be able to run a simple test like this: 我希望能够运行一个像这样的简单测试:

    [TestMethod]
    public void TestExecute5()
    {
        Foo f = new Foo();
        f.GetCustomerInfo(5);
        Assert.AreEqual(10, f.Status);
    }

but obviously its not that simple with the anynchronous methods. 但是显然,使用异步方法并不是那么简单。

There are perhaps 40 asynchronous methods in the ManagementService, called by ~15 different ViewModels - this ViewModel calls about 8 of those asynchronous methods. ManagementService中可能有40个异步方法,由大约15个不同的ViewModel调用-该ViewModel调用了大约8个这些异步方法。 The async calls are implemented through the Event-Based Asynchronous Pattern so we don't have any of the nice 'async' or 'await' functions. 异步调用是通过基于事件的异步模式实现的,因此我们没有任何不错的“异步”或“等待”功能。

What can I do to get tests working in some kind of way that I can call the GetCustomerInfo method and check the status after the callback has completed? 我该怎么做才能以某种方式使测试正常工作,以便可以在回调完成后调用GetCustomerInfo方法并检查状态?

If you are looking to test if an event was fired, you need a way to get into the event handler. 如果要测试是否触发了事件,则需要一种进入事件处理程序的方法。 Since you tagged your question with integration-testsing I am assuming you want to test that the service and viewmodel are working together properly. 由于您使用integration-testsing测试标记了您的问题, integration-testsing我假设您要测试服务和视图模型是否可以正常工作。 If you allow for dependency injection into your view model, you could structure things like this: 如果允许将依赖项注入到视图模型中,则可以构建如下结构:

public class ViewModel
{
    private readonly ManagementService _managementService;
    public ViewModel(ManagementService service)
    {
        _managementService = service;
    }

    public void DoSomething()
    {
        _managementService.DoWork();
    }

}

public class ManagementService
{
    public event EventHandler SomethingHappened;

    public void DoWork()
    {
        System.Threading.Thread.Sleep(2000);
        if (SomethingHappened != null)
            SomethingHappened(this, null);
    }
}

Then when you go to test your view model and service, you can do something like this: 然后,当您测试视图模型和服务时,可以执行以下操作:

[TestMethod, Timeout(5000)]
public void TestMethod1()
{
    var testManagementService = new ManagementService();
    AutoResetEvent evt = new AutoResetEvent(false);
    testManagementService.SomethingHappened += delegate (System.Object o, System.EventArgs e)
    {
        evt.Set();
    };

    var vm = new ViewModel(testManagementService);
    evt.WaitOne();
}

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

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