首页 > 解决方案 > 如何模拟工厂模式以支持单元测试?

问题描述

我有两个操作要做。一个是为了Air transport,一个是为了Road transport。两个过程都有一些message

这里是Interface

   public interface IProcess
   {
        void Process(string message);
   }

这是我的实现Road transport

     public class RoadTransport: IProcess 
     {
         public void Process(string msg)
         {
             // do some road related operation
          }
     }

这是我的实现Air transport

     public class AirTransport: IProcess 
     {
         public void Process(string msg)
         {
             // do some air related operation
         }
     }

现在,我将展示工厂类,它将根据不同的对象返回不同的对象 ID

   public class MyFactory
   {
        private readonly AirTransport airtransport = null;
        private readonly RoadTransport roadtransport = null;

        public MyFactory(AirTransport, RoadTransport)// dependency injected
        {
             airtransport =  AirTransport;
             roadtransport = RoadTransport;
        }
        IProcess process = null;
        public IProcess GetInstance(int id)
        {
              swicth(id)
              {
                    case "1":
                    process = airtransport;
                    break;

                    case "2":
                    process = roadtransport;
                    break; 
              }
             return process;
        }
   }

这是我应该测试的课程

  public class HomeController:Controller
  {
        private readonly MyFactory _myfactory;
        private readonly MyConfigurations _myConfigurations;

        public HomeController(MyFactory factory, MyConfigurations configurations)
        {
             _myfactory = factory;
        }

        public IActionResult Index()
        {
             return View();
        }

        Public ActionResult Process(string message, string id)
        {
            var configurations =  _myConfigurations;
            if(configurations!=null)
            {
               IProcess processor=  _myfactory.GetInstance(id);
               processor.Process(message);
               return View("Index");
            }
        }
  }

我如何对这个控制器进行单元测试,因为没有interfacefactor类定义?我必须参加mock工厂课程还是设计错误?

标签: c#unit-testingdependency-injectiontdd

解决方案


我必须模拟工厂类吗

没有。不要模拟实现问题,模拟抽象。

还是设计错误?

这不是一个灵活的设计,因为您的类与不适合独立单元测试的具体/实现问题紧密耦合。

我如何对这个控制器进行单元测试,因为没有为因子类定义接口?

然后为工厂定义一个抽象(契约)。(可以是接口或抽象类)

public interface IProcessFactory {
    IProcess GetInstance(int id);
}

并让实现派生自抽象

public class MyFactory : IProcessFactory {
    //...
}

现在可以重构控制器以通过构造函数注入显式依赖抽象。

public class HomeController : Controller {
    private readonly IProcessFactory factory;
    private readonly MyConfigurations configurations;

    public HomeController(IProcessFactory factory, MyConfigurations configurations) {
        this.factory = factory;
        this.configurations = configurations;
    }

    //...omitted for brevity

}

现在,这允许在单独测试控制器时替换模拟。

假设是MyConfigurationsPOCO 存储不属于需要抽象的功能问题的设置/选项。

最后一步是确保将实际派生的工厂实现注入到生产中的控制器中。


推荐阅读