1

更新

我想根据它的方法使用来确定是否应该对工厂进行单元测试,因为如果我想测试它,我需要使用 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;

        }
}
4

3 回答 3

1

您必须准备适合此测试的容器(即具有Risk可解析的类)。使用您当前的实现,您无能为力。

当然,这引发了关于这是否是单元测试的问题,但我们可以假设统一已经过良好测试并且可以工作(即假设它不会成为单元测试的可能失败点)。

这是代码中对 IoC 容器的强烈依赖的自然缺点。有人可能会争辩说你可以用你的自定义抽象包装容器......然后注入它?这感觉不对,我还没有看到有人这样做。

有关相关问题,请参阅此问题

于 2012-04-26T10:01:50.763 回答
1

你不能像这样测试:

[设置]
公共无效设置()
{
  // 这里的代码设置容器....
}

[测试]
公共无效example_test()
{
  var factory = new RiskFactory();
  var risk = factory.CreateGoldRisk("xxxx");
  Assert.True(风险为Risk1);
}

在旁注中。你有一个 IOC 容器。然后在工厂包装的容器包装纸。你的架构可能有太多的抽象层..

于 2012-04-26T10:03:07.683 回答
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>();
于 2012-04-26T16:47:11.110 回答