请注意,我对单元测试非常陌生,所以请耐心等待。我有一个方法,使用后台工作程序来调用我的解决方案中另一个项目中的类的方法,并且我发现很难将我的大脑包围在单元测试中。
这基本上是该方法的作用:
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()
返回特定值吗?这两个概念对我来说都很新鲜。是否需要进行重构以使其更易于单元测试?如果是这样,需要做出哪些改变?
答案 0 :(得分:0)
我会将DoWork转移到一个单独的方法,因为它比测试异步/多线程代码更容易测试它。
如果你只是需要测试是否调用了Login,那么mock / shim可能就是这样。此外,通过构造函数将AssetManager模型注入到AssetManagerService实例中会更容易。
此外,模拟界面更容易。也许你可以从AssetManager中提取一个接口,模拟它并通过构造函数将它注入到AssetManagerInstance中。要模拟界面,您不一定需要垫片。像NSubstitute这样的简单模拟框架可以完成这项工作。使用NSubstitute,您还可以告诉mock在调用Login()时返回特定值。