Mock lazy interface with Moq(使用 Moq 模拟惰性接口)
问题描述
我想要模拟惰性接口,但我得到 object reference not set to an instance of an object
异常.
这是正在测试的课程:
公共类 ProductServiceService : IProductServiceService{私有只读 Lazy<IProductServiceRepository>_存储库;私有只读 Lazy<IProductPackageRepository>_productPackageRepository;公共产品服务服务(懒惰的<IProductServiceRepository>存储库,懒惰的<IProductPackageRepository>productPackageRepository){_repository = 存储库;_productPackageRepository = productPackageRepository;}公共异步任务<OperationResult>ValidateServiceAsync(ProductServiceEntity 服务){var 错误 = 新列表<ValidationResult>();if (!await _productPackageRepository.Value.AnyAsync(p => p.Id == service.PackageId))errors.Add(new ValidationResult(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));...返回错误.Any()?OperationResult.Failed(errors.ToArray()): OperationResult.Success();}}
这里是测试类
[Fact, Trait("Category", "Product")]公共异步任务 Create_Service_With_Null_Financial_ContactPerson_Should_Fail(){//安排var entity = ObjectFactory.Service.CreateService(packageId: 1);var fakeProductServiceRepository = new Mock<Lazy<IProductServiceRepository>>();var repo=new Mock<IProductPackageRepository>();repo.Setup(repository => repository.AnyAsync(It.IsAny<Expression<Func<ProductPackageEntity, bool>>>()));var fakeProductPackageRepository = new Lazy<IProductPackageRepository>(() => repo.Object);var sut = new ProductServiceService(fakeProductServiceRepository.Object, fakeProductPackageRepository);//行为var 结果 = 等待 sut.AddServiceAsync(service);//断言断言.假(结果.成功);Assert.Contains(result.ErrorMessages, error => error.Contains(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));}
fakeProductPackageRepository
始终为空.我关注了这篇博文,但仍然收到空引用异常.
这是您示例的重构版本:
[Fact, Trait("Category", "Product")]公共异步任务 Create_Service_With_Null_Financial_ContactPerson_Should_Fail() {//安排var entity = ObjectFactory.Service.CreateService(packageId = 1);var productServiceRepositoryMock = new Mock();var productPackageRepositoryMock = new Mock();productPackageRepositoryMock.Setup(repository => repository.AnyAsync(It.IsAny<Expression<Func<ProductPackageEntity, bool>>>())).ReturnsAsync(false);//利用 Lazy<T>(Func<T>()) 构造函数返回模拟实例var lazyProductPackageRepository = new Lazy<IProductPackageRepository>(() => productPackageRepositoryMock.Object);var lazyProductServiceRepository = new Lazy<IProductServiceRepository>(() => productServiceRepositoryMock.Object);var sut = new ProductServiceService(lazyProductServiceRepository,lazyProductPackageRepository);//行为var 结果 = 等待 sut.AddServiceAsync(service);//断言断言.假(结果.成功);Assert.Contains(result.ErrorMessages, error => error.Contains(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));}
更新
以下最小、完整和可验证的示例在测试时通过.
[TestClass]公共类 MockLazyOfTWithMoqTest {[测试方法]公共异步任务 Method_Under_Test_Should_Return_True() {//安排var productServiceRepositoryMock = new Mock();var productPackageRepositoryMock = new Mock();productPackageRepositoryMock.Setup(repository => repository.AnyAsync()).ReturnsAsync(false);//利用 Lazy<T>(Func<T>()) 构造函数返回模拟实例var lazyProductPackageRepository = new Lazy<IProductPackageRepository>(() => productPackageRepositoryMock.Object);var lazyProductServiceRepository = new Lazy<IProductServiceRepository>(() => productServiceRepositoryMock.Object);var sut = new ProductServiceService(lazyProductServiceRepository,lazyProductPackageRepository);//行为var 结果 = 等待 sut.MethodUnderTest();//断言断言.IsTrue(结果);}公共接口 IProductServiceService { }公共接口 IProductServiceRepository { }公共接口 IProductPackageRepository { 任务<bool>任何异步();}公共类 ProductServiceService : IProductServiceService {私有只读 Lazy<IProductServiceRepository>_存储库;私有只读 Lazy<IProductPackageRepository>_productPackageRepository;公共产品服务服务(懒惰的<IProductServiceRepository>存储库,懒惰的<IProductPackageRepository>productPackageRepository) {_repository = 存储库;_productPackageRepository = productPackageRepository;}公共异步任务<bool>MethodUnderTest() {var 错误 = 新列表<ValidationResult>();if (!await _productPackageRepository.Value.AnyAsync())errors.Add(new ValidationResult("error"));返回错误.Any();}}}
I want mock lazy interface but I got object reference not set to an instance of an object
exception.
Here is class under test:
public class ProductServiceService : IProductServiceService
{
private readonly Lazy<IProductServiceRepository> _repository;
private readonly Lazy<IProductPackageRepository> _productPackageRepository;
public ProductServiceService(
Lazy<IProductServiceRepository> repository,
Lazy<IProductPackageRepository> productPackageRepository)
{
_repository = repository;
_productPackageRepository = productPackageRepository;
}
public async Task<OperationResult> ValidateServiceAsync(ProductServiceEntity service)
{
var errors = new List<ValidationResult>();
if (!await _productPackageRepository.Value.AnyAsync(p => p.Id == service.PackageId))
errors.Add(new ValidationResult(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));
.
.
.
return errors.Any()
? OperationResult.Failed(errors.ToArray())
: OperationResult.Success();
}
}
and here is test class
[Fact, Trait("Category", "Product")]
public async Task Create_Service_With_Null_Financial_ContactPerson_Should_Fail()
{
// Arrange
var entity = ObjectFactory.Service.CreateService(packageId: 1);
var fakeProductServiceRepository = new Mock<Lazy<IProductServiceRepository>>();
var repo= new Mock<IProductPackageRepository>();
repo.Setup(repository => repository.AnyAsync(It.IsAny<Expression<Func<ProductPackageEntity, bool>>>()));
var fakeProductPackageRepository = new Lazy<IProductPackageRepository>(() => repo.Object);
var sut = new ProductServiceService(fakeProductServiceRepository.Object, fakeProductPackageRepository);
// Act
var result = await sut.AddServiceAsync(service);
// Assert
Assert.False(result.Succeeded);
Assert.Contains(result.ErrorMessages, error => error.Contains(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));
}
fakeProductPackageRepository
always is null. I followed this blog post but still I'm getting null reference exception.
How to mock lazy initialization of objects in C# unit tests using Moq
Update:
here is a screen that indicates fakeProductPackageRepository
is null.
Here is a refactored version of your example:
[Fact, Trait("Category", "Product")]
public async Task Create_Service_With_Null_Financial_ContactPerson_Should_Fail() {
// Arrange
var entity = ObjectFactory.Service.CreateService(packageId = 1);
var productServiceRepositoryMock = new Mock<IProductServiceRepository>();
var productPackageRepositoryMock = new Mock<IProductPackageRepository>();
productPackageRepositoryMock
.Setup(repository => repository.AnyAsync(It.IsAny<Expression<Func<ProductPackageEntity, bool>>>()))
.ReturnsAsync(false);
//Make use of the Lazy<T>(Func<T>()) constructor to return the mock instances
var lazyProductPackageRepository = new Lazy<IProductPackageRepository>(() => productPackageRepositoryMock.Object);
var lazyProductServiceRepository = new Lazy<IProductServiceRepository>(() => productServiceRepositoryMock.Object);
var sut = new ProductServiceService(lazyProductServiceRepository, lazyProductPackageRepository);
// Act
var result = await sut.AddServiceAsync(service);
// Assert
Assert.False(result.Succeeded);
Assert.Contains(result.ErrorMessages, error => error.Contains(string.Format(NameMessageResource.NotFoundError, NameMessageResource.ProductPackage)));
}
UPDATE
The following Minimal, Complete, and Verifiable example of your stated issue passes when tested.
[TestClass]
public class MockLazyOfTWithMoqTest {
[TestMethod]
public async Task Method_Under_Test_Should_Return_True() {
// Arrange
var productServiceRepositoryMock = new Mock<IProductServiceRepository>();
var productPackageRepositoryMock = new Mock<IProductPackageRepository>();
productPackageRepositoryMock
.Setup(repository => repository.AnyAsync())
.ReturnsAsync(false);
//Make use of the Lazy<T>(Func<T>()) constructor to return the mock instances
var lazyProductPackageRepository = new Lazy<IProductPackageRepository>(() => productPackageRepositoryMock.Object);
var lazyProductServiceRepository = new Lazy<IProductServiceRepository>(() => productServiceRepositoryMock.Object);
var sut = new ProductServiceService(lazyProductServiceRepository, lazyProductPackageRepository);
// Act
var result = await sut.MethodUnderTest();
// Assert
Assert.IsTrue(result);
}
public interface IProductServiceService { }
public interface IProductServiceRepository { }
public interface IProductPackageRepository { Task<bool> AnyAsync();}
public class ProductServiceService : IProductServiceService {
private readonly Lazy<IProductServiceRepository> _repository;
private readonly Lazy<IProductPackageRepository> _productPackageRepository;
public ProductServiceService(
Lazy<IProductServiceRepository> repository,
Lazy<IProductPackageRepository> productPackageRepository) {
_repository = repository;
_productPackageRepository = productPackageRepository;
}
public async Task<bool> MethodUnderTest() {
var errors = new List<ValidationResult>();
if (!await _productPackageRepository.Value.AnyAsync())
errors.Add(new ValidationResult("error"));
return errors.Any();
}
}
}
这篇关于使用 Moq 模拟惰性接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Moq 模拟惰性接口
基础教程推荐
- 如何激活MC67中的红灯 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- rabbitmq 的 REST API 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01