问题描述
我想编写以下方法的 xunit 测试用例。您能否建议替代设计,以便我可以在当前项目中以最小的更改编写 xunit 测试用例。
public ActionResult Index(int id = 0,AssetFilterType filter = AssetFilterType.All)
{
using (var tracer = new Tracer("AssetController","Index"))
{
RemoveReturnUrl();
ViewBag.JobId = id;
var response = ContextFactory.Current.GetDomain<EmployeeDomain>().GetEmployeeFilterAsync(id,CurrentUser.CompanyId,filter); // Not able write unit test case,please suggest alternate design.
return View("View",response);
}
}
目前的设计如下
public interface IDomain
{
}
public interface IContext
{
D GetDomain<D>() where D : IDomain;
string ConnectionString { get; }
}
public class ApplicationContext : IContext
{
public D GetDomain<D>() where D : IDomain
{
return (D)Activator.CreateInstance(typeof(D));
}
public string ConnectionString
{
get
{
return "DatabaseConnection";
}
}
}
public class ContextFactory
{
private static IContext _context;
public static IContext Current
{
get
{
return _context;
}
}
public static void Register(IContext context)
{
_context = context;
}
}
//var response = ContextFactory.Current.GetDomain****().GetEmployeeFilterAsync(id,CompanyId,过滤器);
此行用于调用特定的类方法,即来自 EmployeeDomain 的 GetEmployeeFilterAsync。虽然它在我们的应用程序中非常方便且广泛使用,但由于设计问题我无法编写单元
测试用例。
能否请您提出设计建议,以便我们可以以最少的更改编写单元测试用例。
解决方法
不要使用 Service Locator anti-pattern,而是使用构造函数注入。我无法从 OP 中分辨出 AssetDomain
是什么,但似乎依赖关系很重要。将其注入到类中:
public class ProbablySomeController
{
public ProbablySomeController(AssetDomain assetDomain)
{
AssetDomain = assetDomain;
}
public AssetDomain AssetDomain { get; }
public ActionResult Index(int id = 0,AssetFilterType filter = AssetFilterType.All)
{
using (var tracer = new Tracer("AssetController","Index"))
{
RemoveReturnUrl();
ViewBag.JobId = id;
var response = AssetDomain.GetAssetFilterAsync(id,CurrentUser.CompanyId,filter);
return View("View",response);
}
}
}
假设 AssetDomain
是多态类型,您现在可以编写测试并注入 Test Double:
[Fact]
public void MyTest()
{
var testDouble = new AssetDomainTestDouble();
var sut = new ProbablySomeController(testDouble);
var actual = sut.Index(42,AssetFilterType.All);
// Put assertions here
}