Unit testing 单元测试中的模拟
我正在尝试测试以下Unit testing 单元测试中的模拟,unit-testing,moq,fluentvalidation,xunit.net,Unit Testing,Moq,Fluentvalidation,Xunit.net,我正在尝试测试以下类别服务的AddCategory 我的问题是,我很难理解该嘲笑/假装什么 我的考试成绩很差 我正在使用MOQ、xUnit和FluentAssertions 我正在为验证器使用FluentValidation 分类服务 public class CategoryService : ValidatingServiceBase, ICategoryService { private readonly IUnitOfWork unitOfWork; private re
类别服务的AddCategory
我的问题是,我很难理解该嘲笑/假装什么
我的考试成绩很差
我正在使用MOQ、xUnit和FluentAssertions
我正在为验证器使用FluentValidation
分类服务
public class CategoryService : ValidatingServiceBase, ICategoryService
{
private readonly IUnitOfWork unitOfWork;
private readonly IRepository<Category> categoryRepository;
private readonly IRepository<SubCategory> subCategoryRepository;
private readonly IValidationService validationService;
public CategoryService(
IUnitOfWork unitOfWork,
IRepository<Category> categoryRepository,
IRepository<SubCategory> subCategoryRepository,
IValidationService validationService)
: base(validationService)
{
this.unitOfWork = unitOfWork;
this.categoryRepository = categoryRepository;
this.subCategoryRepository = subCategoryRepository;
this.validationService = validationService;
}
public bool AddCategory(Category category)
{
var validationResult = validationService.Validate(category);
if (!validationResult.IsValid)
{
return false;
}
else
{
categoryRepository.Add(category);
return true;
}
}
public bool DoesCategoryExist(string categoryName)
{
return categoryRepository.Query().SingleOrDefault(x => x.Name == categoryName) != null;
}
}
public class ValidationService : ServiceBase, IValidationService
{
private readonly IValidatorFactory validatorFactory;
public ValidationService(IValidatorFactory validatorFactory)
{
Enforce.ArgumentNotNull(validatorFactory, "validatorFactory");
this.validatorFactory = validatorFactory;
}
public ValidationResult Validate<TEntity>(TEntity entity) where TEntity : class
{
var validator = validatorFactory.GetValidator<TEntity>();
return validator.Validate(entity);
}
}
公共类CategoryService:ValidatingServiceBase,ICategoryService
{
私有只读IUnitOfWork;
私有只读存储类别存储;
专用只读IRepository子类别存储库;
私有只读IValidationService validationService;
公共类别服务(
i工作单元工作单元,
I假定类别报告,
i存储子类别存储库,
IValidationService验证服务)
:base(validationService)
{
this.unitOfWork=unitOfWork;
this.categoryRepository=categoryRepository;
this.subcategory repository=subcategory repository;
this.validationService=validationService;
}
公共布尔添加类别(类别)
{
var validationResult=validationService.Validate(类别);
如果(!validationResult.IsValid)
{
返回false;
}
其他的
{
categoryRepository.Add(类别);
返回true;
}
}
public bool DoesCategoryExist(字符串类别名称)
{
return categoryRepository.Query().SingleOrDefault(x=>x.Name==categoryName)!=null;
}
}
验证服务
public class CategoryService : ValidatingServiceBase, ICategoryService
{
private readonly IUnitOfWork unitOfWork;
private readonly IRepository<Category> categoryRepository;
private readonly IRepository<SubCategory> subCategoryRepository;
private readonly IValidationService validationService;
public CategoryService(
IUnitOfWork unitOfWork,
IRepository<Category> categoryRepository,
IRepository<SubCategory> subCategoryRepository,
IValidationService validationService)
: base(validationService)
{
this.unitOfWork = unitOfWork;
this.categoryRepository = categoryRepository;
this.subCategoryRepository = subCategoryRepository;
this.validationService = validationService;
}
public bool AddCategory(Category category)
{
var validationResult = validationService.Validate(category);
if (!validationResult.IsValid)
{
return false;
}
else
{
categoryRepository.Add(category);
return true;
}
}
public bool DoesCategoryExist(string categoryName)
{
return categoryRepository.Query().SingleOrDefault(x => x.Name == categoryName) != null;
}
}
public class ValidationService : ServiceBase, IValidationService
{
private readonly IValidatorFactory validatorFactory;
public ValidationService(IValidatorFactory validatorFactory)
{
Enforce.ArgumentNotNull(validatorFactory, "validatorFactory");
this.validatorFactory = validatorFactory;
}
public ValidationResult Validate<TEntity>(TEntity entity) where TEntity : class
{
var validator = validatorFactory.GetValidator<TEntity>();
return validator.Validate(entity);
}
}
公共类验证服务:ServiceBase,IValidationService
{
私有只读IValidatorFactory验证工厂;
公共验证服务(IValidatorFactory validatorFactory)
{
Enforce.ArgumentNotNull(validatorFactory,“validatorFactory”);
this.validatorFactory=validatorFactory;
}
公共验证结果验证(TEntity实体),其中TEntity:类
{
var validator=validatorFactory.GetValidator();
返回validator.Validate(实体);
}
}
验证程序工厂
public class ValidatorFactory : IValidatorFactory
{
public IValidator GetValidator(Type type)
{
Enforce.ArgumentNotNull(type, "type");
return DependencyResolver.Current.GetService(typeof(IValidator<>).MakeGenericType(type)) as IValidator;
}
public IValidator<T> GetValidator<T>()
{
return DependencyResolver.Current.GetService<IValidator<T>>();
}
}
公共类验证器工厂:IValidatorFactory
{
公共IValidator GetValidator(类型)
{
Enforce.ArgumentNotNull(类型,“类型”);
将DependencyResolver.Current.GetService(typeof(IValidator.MakeGenericType(type))返回为IValidator;
}
公共IValidator GetValidator()
{
返回DependencyResolver.Current.GetService();
}
}
类别验证程序
public class CategoryValidator : AbstractValidator<Category>
{
public CategoryValidator(ICategoryService service)
{
RuleFor(x => x.Name)
.NotEmpty()
.Must((category, name) =>
{
return service.DoesCategoryExist(name);
});
}
}
public类CategoryValidator:AbstractValidator
{
公共类别验证人(ICategoryService)
{
RuleFor(x=>x.Name)
.NotEmpty()
.必须((类别、名称)=>
{
退货服务。DoesCategoryExist(名称);
});
}
}
单元测试尝试
[Fact]
public void AddCategory_Should_ReturnTrue()
{
var category = new Category() { Name = "Cat1" };
var unitOfWork = new Mock<IUnitOfWork>();
var categoryRepo = new Mock<IRepository<Category>>();
var subCategoryRepo = new Mock<IRepository<SubCategory>>();
var mockCategoryService = new Mock<ICategoryService>();
var categoryValidator = new CategoryValidator(mockCategoryService.Object);
var validatorFactory = new Mock<IValidatorFactory>();
validatorFactory.Setup(x => x.GetValidator<CategoryValidator>()).Returns(categoryValidator as IValidator<CategoryValidator>);
var validationService = new ValidationService(validatorFactory.Object);
var categoryService = new CategoryService(
unitOfWork.Object,
categoryRepo.Object,
subCategoryRepo.Object,
validationService);
categoryService.AddCategory(category);
}
[事实]
public void AddCategory_Should_ReturnTrue()
{
var category=new category(){Name=“Cat1”};
var unitOfWork=new Mock();
var categoryRepo=new Mock();
var subcategory repo=new Mock();
var mockCategoryService=new Mock();
var categoryValidator=新的categoryValidator(mockCategoryService.Object);
var validatorFactory=newmock();
Setup(x=>x.GetValidator()).Returns(categoryValidator作为IValidator);
var validationService=新的validationService(validatorFactory.Object);
var categoryService=新的categoryService(
工作单元。对象,
类别报告对象,
子类别repo.Object,
验证服务);
categoryService.AddCategory(类别);
}
对于AddCategory方法,我认为您实际上只需要两个模拟,一个用于ValidationService,另一个用于CategoryRepository,因为其他依赖项没有在该函数中执行,因此不相关
(如果你的CCTR抛出空参数,这个故事可能会有所不同,但在这种情况下,我认为你还行——尽管你可能会考虑在将来添加这些检查):
无论如何,由于学究式,我几乎倾向于为这个函数编写两个(或更多个——可能一个用于null输入,以验证它抛出或返回false或其他什么)“单元”测试
- 验证给定无效类别时,函数返回false
- 验证给定有效类别时,函数调用CategoryRepository依赖项上的Add
所以它看起来是这样的(抱歉,这是使用MSTest语法,因为我不熟悉xUnit,但这是相同的想法)。还未测试以下打字错误等:)
public void AddCategory\u InvalidCategory\u ShouldReturnFalse()
{
//安排
var mockValidator=new Mock();
//无论我们传递给验证器什么,它都将返回false
mockValidator.Setup(v=>v.Validate(It.IsAny())。返回(false);
var sut=newcategoryservice(null,null,null,mockValidator.Object);
bool预期值=假;
//表演
bool-actual=sut.AddCategory(新类别());
//断言
AreEqual(预期的,实际的,“验证器没有按预期返回false”);
}
public void AddCategory_ValidCategory_ShouldCallRepositoryAdd()
{
//安排
var mockValidator=new Mock();
//无论我们传递给验证器什么,它都将返回true
mockValidator.Setup(v=>v.Validate(It.IsAny())。返回(true);
var mockRepo=new Mock();
mockRepo.Setup(r=>r.Add(It.IsAny());//不知道或不关心会发生什么,因为这是一个void方法。
var sut=newcategoryservice(null,mockRepo.Object,null,mockValidator.Object);
bool预期值=假;
//表演
bool-actual=sut.AddCategory(新类别());
//断言
验证(r=>r.Add(It.IsAny(),Times.justice(1),“repoadd方法未调用或调用次数过多,等等”);
阿雷先生