我有两个操作要做。一个是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
出厂类还是设计错误?
我必须嘲笑工厂类
吗
不。不要嘲笑实现问题,嘲笑抽象。
还是设计错误?
它不是一个灵活的设计,因为您的类与具体/实现问题紧密耦合,不适合孤立的单元测试。
如何对此控制器进行单元测试,因为没有为因子类定义接口?
然后为工厂定义一个抽象(协定(。(可以是接口或抽象类(
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 存储设置/选项,不属于需要抽象的功能问题。
最后一步是确保实际派生的工厂实现在生产中注入控制器。