如何解决如何模拟 Autofac.Multitenant.MultitenantContainer.ConfigureTenant
private readonly ITenantProvdier _tenantProvider;
//ctor ...
public void ConfigureNewTenants( MultitenantContainer multiTenantContainer )
{
var tenants = _tenantProvider.GetNewTenantsToAdd(); //gets tenants that are just added during the runtime.
foreach( var tenant in tenants )
{
try
{
multiTenantContainer.ConfigureTenant( tenant.Id,someCustomAction);
}
catch( ArgumentNullException exception )
{
// log error and do smth
}
catch( InvalidOperationException exception )
{
// log error and do smth
}
}
}
我的目标是测试 multiTenantContainer
抛出 ArgumentNullException
或 InvalidOperationException
时的代码行为。
我正在使用 NUnit 和 Moq。 并尝试做下一个:
var containerMock = new Mock<MultitenantContainer>();
containerMock
.Setup(c => c.ConfigureTenant(It.IsAny<object>,It.IsAny<Action<ContainerBuilder>>)
.Thows(someException);
但它不起作用,因为方法 ConfigureTenant
有下一个签名:public void ConfigureTenant(object tenantId,Action<ContainerBuilder> configuration)
。并且不能模拟非虚拟类方法。
我尝试使用 virtual new
方法创建派生类。它没有帮助。
解决方法
伙计。在您的示例中,您将收到这样的错误:
Unsupported expression: c => c.ConfigureTenant(It.IsAny<object>(),It.IsAny<Action<ContainerBuilder>>())
Non-overridable members (here: MultitenantContainer.ConfigureTenant) may not be used in setup / verification expressions.
Moq
说他不能模拟非虚方法。
我们有解决方案吗? - 是的!
您需要从方法中提取 interface
并模拟它或将方法标记为 virtual
。在您的情况下,最好选择 interface
选项。
让我们试试吧!
我尝试创建类似于您的示例:
- 在接口中包装方法
public interface IConfigureNewTenants
{
void ConfigureNewTenants(MultitenantContainer multiTenantContainer,int id,Action<ContainerBuilder> action);
}
- 为其创建实现
public class NewTenats : IConfigureNewTenants
{
public void ConfigureNewTenants(MultitenantContainer multiTenantContainer,Action<ContainerBuilder> action)
{
multiTenantContainer.ConfigureTenant(id,action);
}
}
- 模拟方法
// Arrnage
configureNewTenantsMock
.Setup(x => x.ConfigureNewTenants(multitenantContainer.Object,It.IsAny<int>(),It.IsAny<Action<ContainerBuilder>>()))
.Throws<InvalidOperationException>();
- 并进行测试!
// Act
Action act = () => manager.ConfigureNewTenants(multitenantContainer.Object);
// Assert
act.Should().Throw<InvalidOperationException>()
.And.Message
.Should().Be("InvalidOperationExceptionMessage");
这是解决问题的主要思路。 完整的解决方案有更多的代码行,这是我为它创建的方式 gist。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。