最小起订量与 Unity 容器单元测试
Moq with Unity Container unit testing
下面是我尝试进行单元测试的生产代码示例。我正在努力解决对正在使用的具体 class 的依赖。
public MyClass(IUnityContainer container)
{
this.unityContainer = container;
}
public string DoWork()
{
var sender = unityContainer.Resolve<IInterface>(); // how to setup this object
var json = sender.Send("something");
var value = serializer.Deserialize<SomeModel>(json);
return value.url;
}
我想模拟此方法使用的 IInterface。我如何在我的单元测试代码中设置它?我觉得这里缺少一些东西。这有一种反模式的味道......
这是 "service locator" antipattern,您可以在其中将依赖项注入容器/控制反转注入到您的逻辑中。
你应该传递它所依赖的IInterface
,这样你就可以控制它可以获取哪些实例。参见 Dependency Injection container in constructor。
如果无法重构 class,则必须在单元测试中注入容器。将容器设置为 return IInterface
的一个实例(或者更确切地说,一个模拟)。像这样:
public void MyUnitTest()
{
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IInterface, YourInstance>();
MyClass classUnderTest = new MyClass(myContainer);
classUnderTest.DoWork();
Assert...
}
请参阅 How to use Unity.RegisterType with Moq? 以模拟 YourInstance
。
我同意 CodeCaster。典型的模式是在构造函数中接受类型为 IInterface 的参数,并将其分配给 class 级变量。
public MyClass(IInterface sender)
{
this.sender = sender;
}
测试时,只需传入您的最小起订量即可。
也就是说,有时我不喜欢通过构造函数传递依赖项。如:
- 我可能需要 class
的多个实例
- 对象只是有条件地需要。
- class 的构造函数可能依赖于直到 运行 时间才确定的其他值。
在那些情况下,将容器作为参数传递是我遇到的唯一解决方案。只需确保将容器的初始实例注册到自身即可。否则,DI 将为您的构造函数提供一个新的(空)容器。如果有人有更好的模式,尤其是与 Unity 一起使用的模式,我很乐意看到它。
下面是我尝试进行单元测试的生产代码示例。我正在努力解决对正在使用的具体 class 的依赖。
public MyClass(IUnityContainer container)
{
this.unityContainer = container;
}
public string DoWork()
{
var sender = unityContainer.Resolve<IInterface>(); // how to setup this object
var json = sender.Send("something");
var value = serializer.Deserialize<SomeModel>(json);
return value.url;
}
我想模拟此方法使用的 IInterface。我如何在我的单元测试代码中设置它?我觉得这里缺少一些东西。这有一种反模式的味道......
这是 "service locator" antipattern,您可以在其中将依赖项注入容器/控制反转注入到您的逻辑中。
你应该传递它所依赖的IInterface
,这样你就可以控制它可以获取哪些实例。参见 Dependency Injection container in constructor。
如果无法重构 class,则必须在单元测试中注入容器。将容器设置为 return IInterface
的一个实例(或者更确切地说,一个模拟)。像这样:
public void MyUnitTest()
{
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IInterface, YourInstance>();
MyClass classUnderTest = new MyClass(myContainer);
classUnderTest.DoWork();
Assert...
}
请参阅 How to use Unity.RegisterType with Moq? 以模拟 YourInstance
。
我同意 CodeCaster。典型的模式是在构造函数中接受类型为 IInterface 的参数,并将其分配给 class 级变量。
public MyClass(IInterface sender)
{
this.sender = sender;
}
测试时,只需传入您的最小起订量即可。 也就是说,有时我不喜欢通过构造函数传递依赖项。如:
- 我可能需要 class 的多个实例
- 对象只是有条件地需要。
- class 的构造函数可能依赖于直到 运行 时间才确定的其他值。
在那些情况下,将容器作为参数传递是我遇到的唯一解决方案。只需确保将容器的初始实例注册到自身即可。否则,DI 将为您的构造函数提供一个新的(空)容器。如果有人有更好的模式,尤其是与 Unity 一起使用的模式,我很乐意看到它。