如何模拟 IOptionsSnapshot 实例进行测试
Posted
技术标签:
【中文标题】如何模拟 IOptionsSnapshot 实例进行测试【英文标题】:How to mock IOptionsSnapshot instance for testing 【发布时间】:2017-04-27 22:29:41 【问题描述】:我有 AbClass
类,它使用 IOptionsSnapshot<AbOptions>
的 asp.net 核心内置 DI 实例(动态配置)。
现在我想测试这个类。
我正在尝试在测试类中实例化AbClass
类,但我不知道如何实例化IOptionsSnapshot<AbOptions>
的实例以注入AbClass
的构造函数。
我尝试使用Mock<IOptionsSnapshot<AbOptions>>.Object
,但我需要为此实例设置一些值,因为在 AbClass 中,代码正在使用此值 (var x = _options.cc.D1
)。
所以我有一个类似的代码
var builder = new ConfigurationBuilder();
builder.AddInMemoryCollection(new Dictionary<string, string>
["Ab:cc:D1"] = "https://",
["Ab:cc:D2"] = "123145854170887"
);
var config = builder.Build();
var options = new AbOptions();
config.GetSection("Ab").Bind(options);
但我不知道如何链接此 Options 和 IOptionsSnapshot 模拟。
抽象类:
public class AbClass
private readonly AbOptions _options;
public AbClass(IOptionsSnapshot<AbOptions> options)
_options = options.Value;
private void x()var t = _options.cc.D1
我的测试实例化这个类:
var service = new AbClass(new Mock???)
并且需要在AbClass
中测试一个调用x()
的方法,但是当它在_options.cc.D1
上时它会抛出ArgumentNullException
【问题讨论】:
好问题!对于IOptions<T>
,Options
类上有一个静态的Create
方法,但对于IOptionsSnapshot<T>
,我没有等效的方法。很好奇答案是什么。
【参考方案1】:
您应该能够模拟界面并为测试创建选项类的实例。由于我不知道选项类的嵌套类,因此我做了一个广泛的假设。
Documentation: IOptionsSnapshot
//Arrange
//Instantiate options and nested classes
//making assumptions here about nested types
var options = new AbOptions()
cc = new cc
D1 = "https://",
D2 = "123145854170887"
;
var mock = new Mock<IOptionsSnapshot<AbOptions>>();
mock.Setup(m => m.Value).Returns(options);
var service = new AbClass(mock.Object);
对嵌套值的访问现在应该返回正确的值而不是 NRE
【讨论】:
【参考方案2】:通用方式:
public static IOptionsSnapshot<T> CreateIOptionSnapshotMock<T>(T value) where T : class, new()
var mock = new Mock<IOptionsSnapshot<T>>();
mock.Setup(m => m.Value).Returns(value);
return mock.Object;
用法:
var mock = CreateIOptionSnapshotMock(new AbOptions()
cc = new cc
D1 = "https://",
D2 = "123145854170887"
);
【讨论】:
以上是关于如何模拟 IOptionsSnapshot 实例进行测试的主要内容,如果未能解决你的问题,请参考以下文章