我希望能够对这段代码进行单元测试
有哪些特定的问题阻止您对这个类进行单元测试?它有两种方法,编写单元测试似乎非常简单。
名字是CarFactory,但在我看来,这不像是一个工厂模式
工厂模式
是
工厂方法模式是一种创建模式,它使用工厂方法来处理创建对象的问题,而不必指定要创建的对象的确切类
这并不意味着它不是服务定位器,但它肯定是一种工厂方法。
(老实说,它看起来不像一个服务定位器,因为它只提供一个服务)
Moq不是一个单元测试框架。最小起订量是
. 静态类不容易创建
嘲弄
静态类。。它们还隐藏了依赖关系。
在这个例子中,我想说的是,这个静态类使您无法轻松地模拟它来对依赖于静态类方法的其他方法进行单元测试。
public class CarFactoryTests
{
public class MoqCar : CarBase { }
public void Register_WithValidParameters_DoesNotThrowException
{
// Act
Assert.DoesNotThrow(() => CarFactory.Register<MoqCar>(
nameof(Register_WithValidParameters_DoesNotThrowException)));
}
public void Create_WithValidCar_DoesNotThrowException
{
CarFactory.Register<MoqCar>(
nameof(Create_WithValidParameters_DoesNotThrowException));
Assert.DoesNotThrow(() => CarFactory.Create(
nameof(Create_WithValidParameters_DoesNotThrowException));
}
// etc etc
}
你可能遇到的问题是
public class CarConsumer
{
public void ICar GetRedCar()
{
var result = CarFactory.Create("Tesla");
result.Color = Color.Red;
return result;
}
}
测试此方法意味着您不能完全控制该方法,因为存在外部代码
GetRedCar()
这就是为什么你必须把汽车工厂改造成汽车工厂的原因
实例类
public class CarConsumer
{
private ICarFactory _carFactory;
public CarConsumer(ICarFactory carFactory)
{
_carFactory = carFactory;
}
public void ICar GetRedCar()
{
var result = _carFactory.Create("Tesla");
result.Color = Color.Red;
return result;
}
}
现在我们可以开始最小起订量了
ICarfactory
GetRedCar()
.
以下是不推荐的。
public class CarConsumer
{
private Func<string, ICar> _createCar;
public CarConsumer(Func<string, ICar> createCar= CarFactory.Create)
{
_createCar = createCar;
}
public void ICar GetRedCar()
{
var result = _createCar("Tesla");
result.Color = Color.Red;
return result;
}
}
我们可以禁止这种类型的函数,但它实际上只是解决实际问题的一根拐杖。
我想我真正的问题是如何制作我的CarFactory,以便使用它的其他类的方法可以使用Moq进行测试?
public interface ICarFactory
{
void Register<TCar>(string car) where TCar : CarBase, new();
ICar Create(string car);
}
public class CarFactory : ICarFactory
{
private readonly IDictionary<string, Type> CarsRegistry
= new Dictionary<string, Type>();
public void Register<TCar>(string car) where TCar : CarBase, new()
{
if (!CarsRegistry.ContainsKey(car))
{
CarsRegistry.Add(car, typeof(TCar));
}
}
public ICar Create(string car)
{
if (CarsRegistry.ContainsKey(car))
{
CarBase newCar = (CarBase)Activator.CreateInstance(CarsRegistry[car]);
return newCar;
}
throw new NotSupportedException($"Unknown '{car}'");
}
}