使用调用另一个方法的后台工作程序对void方法进行单元测试?

时间:2013-11-19 18:02:02

标签: c# unit-testing visual-studio-2012 refactoring

请注意,我对单元测试非常陌生,所以请耐心等待。我有一个方法,使用后台工作程序来调用我的解决方案中另一个项目中的类的方法,并且我发现很难将我的大脑包围在单元测试中。

这基本上是该方法的作用:

public void VerifyLocation()
{
    this.IsBusy = true;

    using (BackgroundWorker worker = new BackgroundWorker())
    {
        worker.DoWork += (sender, e) =>
        {
            Context context = Profile.GetContext();

            AssetManagerService svc = new AssetManagerService(context);
            this.Status = svc.Login();

            if (this.Status == AssetManagerLoginStatus.Success)
            {
                //Do stuff
                this.ShowError = false;
            }
            else if (this.Status == AssetManagerLoginStatus.LocationDoesNotExst || this.Status == AssetManagerLoginStatus.LibraryTitleNotDetermined)
                this.ShowError = true;
            else
                this.ShowError = false;
        };

        worker.RunWorkerCompleted += (sender, e) =>
        {
            if (e.Error != null)
            {
                this.ShowError = true;
            }

            this.IsBusy = false;
        };

        worker.RunWorkerAsync();
    }
}

以下是AssetManagerService的示例:

public class AssetManagerService
{
    //AssetManager is an abstract class
    private AssetManager provider = null;

    public AssetManagerService(UnityContext context)
    {
        this.Context = context;
        this.InitializeProvider();
    }

    private void InitializeProvider()
    {
        //Determine provider based on Context properties
    }

    public AssetManagerLoginStatus Login()
    {
        return this.provider.Login();
    }
}

显然,我最关心的是调用Login()方法。我会使用Shim来控制DoWork期间发生的事情吗?我会使用Stub强制Login()返回特定值吗?这两个概念对我来说都很新鲜。是否需要进行重构以使其更易于单元测试?如果是这样,需要做出哪些改变?

1 个答案:

答案 0 :(得分:0)

我会将DoWork转移到一个单独的方法,因为它比测试异步/多线程代码更容易测试它。

如果你只是需要测试是否调用了Login,那么mock / shim可能就是这样。此外,通过构造函数将AssetManager模型注入到AssetManagerService实例中会更容易。

此外,模拟界面更容易。也许你可以从AssetManager中提取一个接口,模拟它并通过构造函数将它注入到AssetManagerInstance中。要模拟界面,您不一定需要垫片。像NSubstitute这样的简单模拟框架可以完成这项工作。使用NSubstitute,您还可以告诉mock在调用Login()时返回特定值。