C# 模拟接口转换回原始类
我的C# 模拟接口转换回原始类,c#,unit-testing,moq,C#,Unit Testing,Moq,我的MongoDbRepository有一个名为IRepository的接口。因此,我模拟接口来设置方法,即UpdateOneAsync。但是,我的MerchantConfigurationRepository只能接受mongodbrespository对象,这就是我需要强制转换它的原因。因为某种原因当我这么做的时候 (MongoDBRepository<MerchantConfigurationEntity>)dataAccess.Object 由于这个原因,您的类应该依赖于抽象
MongoDbRepository
有一个名为IRepository
的接口。因此,我模拟接口来设置方法,即UpdateOneAsync
。但是,我的MerchantConfigurationRepository
只能接受mongodbrespository
对象,这就是我需要强制转换它的原因。因为某种原因当我这么做的时候
(MongoDBRepository<MerchantConfigurationEntity>)dataAccess.Object
由于这个原因,您的类应该依赖于抽象,而不是具体化
MerchantConfigurationRepository
应该依赖于IRepository
,而不是实现mongodbrespository
只要确保您的DI知道在生产中使用实际实现即可。您的类应该依赖于抽象,而不是具体化
MerchantConfiguration存储库
应该依赖于IRepository
而不是实现MongodBrespository
伙计谢谢你给我的大脑注入了一些感觉,当然是DUH!虽然@Nkosi是绝对正确的,但Moq可以模拟类,如var dataAccess=new mock()代码>但它要求类是公共的(除非您将Moq的程序集设置为友元程序集),并具有相关的可访问实例构造函数,您可以为其传递“好”参数,并且只有当您需要设置的方法是虚拟的
或抽象的
(包括覆盖
,无密封
)且可访问。如果是非虚拟成员(包括字段)是的,兄弟,你明白了,这正是我所做的,谢谢你的回答。基本上,我必须改变我的存储库,这样他们才能使用接口。我在使用Moq时总是犯这个错误,为了使单元测试正常工作,你必须改变代码,这有点痛苦,但是最后,这是理想的结构。再次感谢您的回复,您确实帮助了我。
[Fact]
public async void UpdateMerchantSuccessPushesMerchantEntityToDataStore()
{
//Arrange
var originalMerchantConfig = ModelFactory.GetMerchant();
var merchants = new List<MerchantConfigurationEntity>();
var dataAccess = new Mock<IRepository<MerchantConfigurationEntity>>();
dataAccess.Setup(m => m.UpdateOneAsync(It.IsAny<MerchantConfigurationEntity>()))
.Callback((MerchantConfigurationEntity m) => merchants.Add(m))
.Returns(Task.FromResult(1));
var merchantRepo = new MerchantConfigurationRepository((MongoDBRepository<MerchantConfigurationEntity>)dataAccess.Object);
//Act
var result = await merchantRepo.UpdateMerchant(originalMerchantConfig);
//Assert
result.ShouldNotBeNull();
result.Sucess.ShouldBeTrue();
merchants.Count.ShouldBe(1);
merchants[0].merchantId.ShouldBe(originalMerchantConfig.merchantId);
}
public class MerchantConfigurationRepository {
private readonly IRepository<MerchantConfigurationEntity> repository;
public MerchantConfigurationRepository(IRepository<MerchantConfigurationEntity> repositiry) {
this.repository = repository;
}
//...other code
public Task<int> UpdateMerchant(Merchant model) { ... }
}
var merchantRepo = new MerchantConfigurationRepository(dataAccess.Object);