[英]How to update the properties of already registered class in Autofac container in Nunit Framework
我使用依赖注入框架AutoFac
在NUnit
描述在这里
这些类被注册为SingleInstance范围。
其中一个类取决于Setting
类,如下所示:
class Product
{
public (Setting setting, Dep1 dependency) {.... }
....
}
我想针对每个测试用例更新“设置”类之一的属性。
[Test]
public void Test()
{
//Arrange
var setting = Resolve<Setting>
Setting.Id = value
// product depend on two dependency injected via constructor
var product = Resolve<Product> ;
//the problem is: the new values of setting class are not reflected in
//Product, and the Product still use the default values provided by the container
......
}
问题是更新的值未反映在容器中,并且单元测试失败,并且Product
类仍使用default values
我试图用这个解决方案 ,但它不能主动帮助的文档AutoFac不提供使用NUnit的或测试套件的指导方针。
问题:如何更新类setting
的值,并将新值自动注入NUnit中product
类的构造函数中?
你不知道
每个应用程序应具有其自己的“ 合成根” 。 由于测试项目是与被测类不同的应用程序,因此您永远不会与测试配置共享生产配置 。
在进行单元测试时,通常一次不会处理超过六个左右的依赖项。 为此目的设置DI容器是不切实际的。 取而代之的是,您应该重新建立被测类并模拟除DTO和Model对象之外的所有其他内容。
[Test]
public void Test()
{
var setting = new Setting { Value1 = "x", Value2 = "y" };
var dep1 = new Mock<Dep1>();
// setup Moq conditions on dep1
var product = new Product(setting, dep1);
// Execute method on product and assert
}
在进行集成测试时,使用纯DI比仅出于测试目的设置DI容器要好。 但是,如果您确实使用DI容器,则它应具有与正在测试的应用程序不同的独立配置。 即使这不是不好的做法,还是有一些需要嘲笑的依赖关系仍然可以保证这样做。 您不是在测试DI容器配置,而是在测试应用程序的组件 ,因此无需使它们相同。
注意:强烈建议使用抽象而不是具体类型作为构造函数参数。 通常的途径是使用接口(尽管我认为可能不需要“设置”),但是抽象类也可以使用。
您可以创建一个界面来表示您的设置,而不是尝试更新Settings
类的属性,例如
public interface ISettings
{
int Value { get; }
}
将该接口(而不是具体的类)注入到Product
类中。 您的具体实现可以从配置文件中读取,或者您可以使用带有硬编码值的实现-无论您需要什么。
但是,既然您的类依赖于该接口,为了进行测试,您可以使用许多模拟它的选项。
您可以使用双重测试,例如:
public class SettingsDouble : ISettings
{
public int Value { get; set; }
}
或者您可以使用Moq 。
var settingsMock = new Mock<ISettings>();
settingsMock.Setup(x => x.Value).Returns(1);
副作用是您的ISettings
接口和实现可以具有只读属性。 可能是您不想让类在运行时设置这些属性并影响其他类的设置,但是您出于单元测试的目的而将其设置为可写。 现在,您不必这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.