我正在徘徊如何做到这一点,因为它给了我nullreferenceexception。在我的处理程序类中有这个构造函数:
IDbConnection _dbConnection;
Context _context;
SigSettings _settings;
public SignalsHandler(IConfiguration configuration, IDbConnection connection)
{
_dbConnection = connection;
_settings = configuration.GetSection("SigSettings").Get<SigSettings>();
if (_settings == null)
_settings = new SigSettings();
}
我想对这个类做单元测试来测试我的crud方法,但是下面的代码不起作用:
private Mock<IConfiguration> _configuration = new Mock<IConfiguration>();
private Mock<IDbConnection> _connection = new Mock<IDbConnection>();
private readonly SignalsHandler _handler;
public SignalsTest()
{
_handler = new SignalsHandler(_configuration.Object, _connection.Object);
}
它给了我这个错误:System。参数不能为空。Arg_ParamName_Name'在这一行:_settings = configuration.GetSection("SigSettings").Get();
帮忙吗?
_configuration
只是模拟对象,您还需要设置它拥有的方法,否则它们将返回null
,因此configuration.GetSection("SigSettings")
将返回null
。
为了避免这种情况,你需要这样写:
_configuration
.Setup(x => x.GetSection("SigSettings"))
.Returns("some setting");
或更一般地:
_configuration
.Setup(x => x.GetSection(It.IsAny<string>()))
.Returns("some setting");
由于我没有意识到方法返回一些对象而不是string
,这里是完整的设置。通常,您总是为所有方法调用提供mock,因此您将无法获得null
:
var configSectionMock = new Mock<IConfigurationSection>();
var configMock = new Mock<IConfiguration>();
configMock
.Setup(x => x.GetSection(It.IsAny<string>()))
.Returns(configSectionMock.Object);
// Instantiate system under test with mocked object.
var sut = new Sut(configMock.Object);
不模拟IConfiguration
的另一种方法,而是提供实际的实现,提供有用的反馈,而不耦合到测试中类中使用的方法。
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new[]
{
new KeyValuePair<string, string>("SigSettings:One", "value1"),
new KeyValuePair<string, string>("SigSettings:Two", "value2"),
})
.Build();
var sut = new Sut(configuration);
现在在Sut
中,您可以使用不同的方式访问配置值,而无需重写测试。