【问题标题】:How do I mock factory pattern to support unit testing?如何模拟工厂模式以支持单元测试?
【发布时间】:2019-10-03 08:37:11
【问题描述】:

我有两个操作要做。一种用于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");
            }
        }
  }

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

【问题讨论】:

  • 可以将GetInstance方法标记为virtual,然后在继承MyFactory的类中覆盖它
  • 为什么不定义一个IFactory 接口?
  • 首先,为什么控制器与实体紧密耦合而不与抽象松散耦合?

标签: c# unit-testing dependency-injection tdd


【解决方案1】:

我必须要模拟工厂类吗

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

还是设计错误?

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

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

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

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

}

现在可以在单独测试控制器时替换模拟。

假设MyConfigurations 是一个 POCO 存储设置/选项,不属于需要抽象的功能问题。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多