模拟界面转换回原始 class
Mock Interface casting back to original class
我的 MongoDbRepository
有一个名为 IRepository
的界面。所以我正在模拟接口来设置 UpdateOneAsync
的方法。但是我的 MerchantConfigurationRepository
只能接受一个 MongoDbRepository
对象,这就是我需要转换它的原因。出于某种原因,当我这样做时
(MongoDBRepository<MerchantConfigurationEntity>)dataAccess.Object
我收到错误
Unable to cast object of type 'Castle.Proxies.IRepository`1Proxy' to
type 'Newgistics.Common.MongoDb.MongoDBRepository`1
我应该如何设置 Mock 然后传入对象,我尝试将变量设置为 dataAccess.Object
并传入该变量,但如果我这样做,设置将作为 null
。
下面是单元测试:
[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);
}
出于这个原因,您的 类 应该依赖于抽象而不是具体化。 MerchantConfigurationRepository
应该依赖于 IRepository<MerchantConfigurationEntity>
而不是实现 MongoDBRepository<MerchantConfigurationEntity>
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);
只需确保您的 DI 知道在生产中使用实际实现即可。
我的 MongoDbRepository
有一个名为 IRepository
的界面。所以我正在模拟接口来设置 UpdateOneAsync
的方法。但是我的 MerchantConfigurationRepository
只能接受一个 MongoDbRepository
对象,这就是我需要转换它的原因。出于某种原因,当我这样做时
(MongoDBRepository<MerchantConfigurationEntity>)dataAccess.Object
我收到错误
Unable to cast object of type 'Castle.Proxies.IRepository`1Proxy' to type 'Newgistics.Common.MongoDb.MongoDBRepository`1
我应该如何设置 Mock 然后传入对象,我尝试将变量设置为 dataAccess.Object
并传入该变量,但如果我这样做,设置将作为 null
。
下面是单元测试:
[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);
}
出于这个原因,您的 类 应该依赖于抽象而不是具体化。 MerchantConfigurationRepository
应该依赖于 IRepository<MerchantConfigurationEntity>
而不是实现 MongoDBRepository<MerchantConfigurationEntity>
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);
只需确保您的 DI 知道在生产中使用实际实现即可。