簡體   English   中英

測試異步/回調Visual Studio

[英]Testing Asynchronous/Callbacks Visual Studio

我需要為一大堆C#代碼編寫一些測試,類似於下面的示例。 這是我在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();
        }

    }

}

我希望能夠運行一個像這樣的簡單測試:

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

但是顯然,使用異步方法並不是那么簡單。

ManagementService中可能有40個異步方法,由大約15個不同的ViewModel調用-該ViewModel調用了大約8個這些異步方法。 異步調用是通過基於事件的異步模式實現的,因此我們沒有任何不錯的“異步”或“等待”功能。

我該怎么做才能以某種方式使測試正常工作,以便可以在回調完成后調用GetCustomerInfo方法並檢查狀態?

如果要測試是否觸發了事件,則需要一種進入事件處理程序的方法。 由於您使用integration-testsing測試標記了您的問題, integration-testsing我假設您要測試服務和視圖模型是否可以正常工作。 如果允許將依賴項注入到視圖模型中,則可以構建如下結構:

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

然后,當您測試視圖模型和服務時,可以執行以下操作:

[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