更新
我想知道工厂是否应该根据方法的用途进行单元测试,因为如果我想测试它,我需要使用IoC容器注册类型,在我的情况下使用Unity。如果我嘲笑工厂,那就不是实际测试工厂方法了。
下面是一个工厂类,它根据参数创建类型实例。
public class CarFactory
{
public ICar CreateCar(string CarType)
{
ICar Car;
switch (CarType)
{
case RepositoryType.Car1:
Car = Ioc.ContainerWrapper.Resolve<Car1>();
break;
case RepositoryType.Car2:
Car = Ioc.ContainerWrapper.Resolve<Car2>();
break;
default:
Car = Ioc.ContainerWrapper.Resolve<Car3>();
break;
}
return Car;
}
}
class Car1
{
private readonly IRepository1 _IRepository1;
public Car1(IRepository1 repository1)
{
_IRepository1 = repository1;
}
}
答案 0 :(得分:1)
您必须准备适合此测试的容器(即,Risk
类可解析)。根据您当前的实施情况,您无能为力。
当然,这引发了一个问题,即这是否是单元测试,但是我们可以假设统一已经过充分测试并且可以工作(即假设它不会是单元测试的可能失败点)。
在代码中强烈依赖IoC容器的自然缺点。有人可能会说你可以使用自定义抽象包装容器并...并注入它?这感觉不对,我还没有看到有人这样做。
有关相关问题,请参阅this question。
答案 1 :(得分:1)
你不能像这样测试:
[SetUp] public void setup() { // code here to set up the container.... } [Test] public void example_test() { var factory = new RiskFactory(); var risk = factory.CreateGoldRisk("xxxx"); Assert.True(risk is Risk1); }
旁注。你有一个IOC容器。一个容器包装,然后包装在工厂中。您的架构可能有太多的抽象层。
答案 2 :(得分:1)
从我的角度来看,你走的是正确的道路。
工厂的目的是创建一个对象,以便允许他们调用服务定位器(是的,您仍在使用服务定位器反模式,但是您正在将其从您的域移动到工厂)
参考:
https://github.com/ninject/ninject.extensions.factory/wiki
回到你原来的问题,我相信你应该测试你的工厂,以保证你得到正确的对象取决于所使用的参数,关于这是单元测试还是任何类型的集成测试存在争议,我的观点是,在Martin Fowler的这篇文章后,它仍然是一个单元测试:
http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting
这是我测试它的方式:
IRisk myRisk = new RiskFactory().CreateGoldRisk("Risk1");
myRisk.Should().NotBeNull().And.BeOfType<Risk1>();