如何编写紧耦合的工厂设计模式代码块的Xunit测试用例?

问题描述

我想编写以下方法的 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
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...