C# 如何正确测试.net服务逻辑
我有一个功能测试,但我需要如何正确测试逻辑的指导。我对测试的理解是,应该在不与资源紧密耦合的情况下进行测试(这是模拟的原因),但是如果所有内容都被模拟(尤其是返回结果),那么如何在不实例化一组类的情况下正确地测试逻辑呢C# 如何正确测试.net服务逻辑,c#,testing,C#,Testing,我有一个功能测试,但我需要如何正确测试逻辑的指导。我对测试的理解是,应该在不与资源紧密耦合的情况下进行测试(这是模拟的原因),但是如果所有内容都被模拟(尤其是返回结果),那么如何在不实例化一组类的情况下正确地测试逻辑呢 ValidateEmployeeConfigurationAsync(以下)将返回RulesValidationResult,这就是我想要断言的。因此,我可以回答我自己的问题,这需要更新存储库和服务——这是一种方法。是否有一种最佳实践方法来实现这一点?这感觉不对 功能测试 [Te
ValidateEmployeeConfigurationAsync
(以下)将返回RulesValidationResult
,这就是我想要断言的。因此,我可以回答我自己的问题,这需要更新存储库和服务——这是一种方法。是否有一种最佳实践方法来实现这一点?这感觉不对
功能测试
[TestMethod]
公共异步任务PassValidateEmployeeConfigurationTest()
{
//安排
const long employeeId=200L;
const int configurationTypeId=(int)Constants.Configuration.ConfigurationTypes.User;
const bool enabled=真;
_ruleService=newmock();
_configurationService=new Mock();
_ruleFacade=newmock();
_configurationService.Setup(x=>x.GetByConfigurationNameAsync(It.IsAny())
.ReturnsAsync(GetConfigurations(enabled));
_设置(x=>x.GetConfigRulesByEmployeeIdAsync(It.IsAny()))
.ReturnsAsync(GetRules(已启用));
_ruleFacade.Setup(x=>
x、 ValidateEmployeeConfigurationAsync(It.IsAny(),It.IsAny(),It.IsAny())
.ReturnsAsync(GetPassedValidationResult());
//表演
var结果=等待
_ruleFacade.Object.ValidateEmployeeConfigurationAsync(employeeId,“TestConfiguration”,configurationTypeId);
//断言
Assert.IsNotNull(结果);
Assert.AreEqual(true,result.PassedValidation);
}
利息法
public async Task ValidateEmployeeConfigurationAsync(长employeeId,字符串configurationName,int-configurationTypeId=6)
{
var key=GetDefaultKey(configurationName);
var规则=新列表();
var validationResult=新规则validationResult();
validationResult.Messages.Add(“未找到配置”,配置名称);
var configurations=await\u configurationService.GetByConfigurationNameAsync(configurationName);
如果(!configurations.Any())
返回验证结果;
var configuration=configurations.FirstOrDefault(c=>c.ConfigurationTypeId==ConfigurationTypeId);
rules=wait_ruleService.GetConfigRulesByEmployeeIdAsync(employeeId);
if(rules.Any()&&configuration.ConfigurationSettings.Any())
{
var testTargets=new List();
testTargets.AddRange(来自configuration.ConfigurationSettings中的设置
其中setting.IsActive&&setting.Key==Key
选择新配置设置
{
ConfigurationId=设置.ConfigurationId,
Key=setting.Key,
值=设置值
});
if(PassesRules(测试目标、规则))
{
var msg=$“{configurationName}已通过规则验证”;
validationResult.PassedValidation=true;
validationResult.Messages.Clear();
validationResult.Messages.Add(“已通过”,msg);
}
其他的
{
var msg=$“{configurationName}规则验证失败”;
validationResult.Messages.Clear();
validationResult.Messages.Add(“失败”,消息);
}
}
返回验证结果;
}
这就是我构建测试的方式,请查看以前版本的测试方法
以查看差异。在最初的问题中,由于测试的结构方式不正确,测试总是会通过
在此版本中,模拟输入,模拟依赖项,并设置IOC容器,以便测试目标代码,并将断言应用于生成的输出
[TestMethod]
public async Task PassValidateEmployeeConfigurationTest()
{
//ARRANGE
const long employeeId = 200L;
const int configurationTypeId = (int) Constants.Configuration.ConfigurationTypes.User;
//need the IOC container
var unityContainer = new UnityContainer();
//Mock ALL the dependencies (services and repositories)
var ruleFacade = new Mock<IRuleFacade>();
var employeeConfigMapRepo = new Mock<IEmployeeConfigurationMapRepo>();
var ruleRepo = new Mock<IRuleRepo>();
var ruleService = new Mock<IRuleService>();
var configurationService = new Mock<IConfigurationService>();
var employeeConfigurationService = new Mock<IEmployeeConfigurationService>();
var organizationConfigurationService = new Mock<IOrganizationConfigurationService>();
var facilityConfigurationService = new Mock<IFacilityConfigurationService>();
var configurationSettingService = new Mock<IConfigurationSettingService>();
// configure the dependencies so that the proper inputs are available
configurationService.Setup(x => x.GetByConfigurationNameAsync(It.IsAny<string>()))
.ReturnsAsync(GetConfigurations(true));
employeeConfigMapRepo.Setup(x => x.GetAllByEmployeeIdAsync(It.IsAny<int>()))
.ReturnsAsync(GetEmployeeConfigMaps(true));
employeeConfigurationService.Setup(x => x.GetAllByEmployeeIdAsync(It.IsAny<long>()))
.ReturnsAsync(GetEmployeeConfigMaps(true));
ruleRepo.Setup(x => x.GetByConfigurationIdAsync(It.IsAny<int>()))
.ReturnsAsync(GetRules(true));
ruleService.Setup(x => x.GetConfigRulesByEmployeeIdAsync(It.IsAny<long>(), It.IsAny<string>()))
.ReturnsAsync(GetRules(true));
// help the IOC do its thing, map interfaces to Mocked objects
unityContainer.RegisterInstance<IRuleService>(ruleService.Object);
unityContainer.RegisterInstance<IRuleRepo>(ruleRepo.Object);
unityContainer.RegisterInstance<IConfigurationService>(configurationService.Object);
unityContainer.RegisterInstance<IEmployeeConfigurationService>(employeeConfigurationService.Object);
unityContainer.RegisterInstance<IOrganizationConfigurationService>(organizationConfigurationService.Object);
unityContainer.RegisterInstance<IFacilityConfigurationService>(facilityConfigurationService.Object);
unityContainer.RegisterInstance<IConfigurationSettingService>(configurationSettingService.Object);
unityContainer.RegisterInstance<IRuleFacade>(ruleFacade.Object);
// thanks to all the mocking, the facade method ValidateEmployeeConfigurationAsync can now be tested properly
var ruleHelper = unityContainer.Resolve<RuleFacade>();
//ACT
var result = await
ruleHelper.ValidateEmployeeConfigurationAsync(employeeId, _testConfigName, configurationTypeId);
//ASSERT
Assert.IsNotNull(result);
Assert.AreEqual(true, result.PassedValidation);
}
[TestMethod]
公共异步任务PassValidateEmployeeConfigurationTest()
{
//安排
const long employeeId=200L;
const int configurationTypeId=(int)Constants.Configuration.ConfigurationTypes.User;
//需要IOC容器吗
var unityContainer=新的unityContainer();
//模拟所有依赖项(服务和存储库)
var ruleFacade=new Mock();
var employeeConfigMapRepo=new Mock();
var ruleRepo=new Mock();
var ruleService=new Mock();
var configurationService=new Mock();
var employeeConfigurationService=new Mock();
var organizationConfigurationService=new Mock();
var facilityConfigurationService=new Mock();
var configurationSettingService=new Mock();
//配置依赖项,以便提供正确的输入
configurationService.Setup(x=>x.GetByConfigurationNameAsync(It.IsAny())
.ReturnsAsync(GetConfigurations(true));
employeeConfigMapRepo.Setup(x=>x.GetAllByEmployeeIdAsync(It.IsAny()))
.ReturnsAsync(GetEmployeeConfigMaps(true));
employeeConfigurationService.Setup(x=>x.GetAllByEmployeeIdAsync(It.IsAny()))
.ReturnsAsync(GetEmployeeConfigMaps(true));
ruleRepo.Setup(x=>x.GetByConfigurationIdAsync(It.IsAny())
.ReturnsAsync(GetRules(true));
设置(x=>x.GetConfigRulesByEmployeeIdAsync(It.IsAny(),It.IsAny())
.ReturnsAsync(GetRules(true));
//帮助IOC完成任务,将接口映射到模拟对象
unityContainer.RegisterInstance(ruleService.Object);
unityContainer.RegisterInstance(ruleRepo.Object);
unityContainer.RegisterInstance(configurationService.Object);
unityContainer.RegisterInstance(员工配置服务)
public async Task<RulesValidationResult> ValidateEmployeeConfigurationAsync(long employeeId, string configurationName, int configurationTypeId = 6)
{
var key = GetDefaultKey(configurationName);
var rules = new List<Rule>();
var validationResult = new RulesValidationResult();
validationResult.Messages.Add("Configuartion not found", configurationName);
var configurations = await _configurationService.GetByConfigurationNameAsync(configurationName);
if (!configurations.Any())
return validationResult;
var configuration = configurations.FirstOrDefault(c => c.ConfigurationTypeId == configurationTypeId);
rules = await _ruleService.GetConfigRulesByEmployeeIdAsync(employeeId);
if (rules.Any() && configuration.ConfigurationSettings.Any())
{
var testTargets = new List<ConfigurationSetting>();
testTargets.AddRange(from setting in configuration.ConfigurationSettings
where setting.IsActive && setting.Key == key
select new ConfigurationSetting
{
ConfigurationId = setting.ConfigurationId,
Key = setting.Key,
Value = setting.Value
});
if (PassesRules(testTargets, rules))
{
var msg = $"{configurationName} passed rule validation";
validationResult.PassedValidation = true;
validationResult.Messages.Clear();
validationResult.Messages.Add("Passed", msg);
}
else
{
var msg = $"{configurationName} failed rule validation";
validationResult.Messages.Clear();
validationResult.Messages.Add("Failed", msg);
}
}
return validationResult;
}
[TestMethod]
public async Task PassValidateEmployeeConfigurationTest()
{
//ARRANGE
const long employeeId = 200L;
const int configurationTypeId = (int) Constants.Configuration.ConfigurationTypes.User;
//need the IOC container
var unityContainer = new UnityContainer();
//Mock ALL the dependencies (services and repositories)
var ruleFacade = new Mock<IRuleFacade>();
var employeeConfigMapRepo = new Mock<IEmployeeConfigurationMapRepo>();
var ruleRepo = new Mock<IRuleRepo>();
var ruleService = new Mock<IRuleService>();
var configurationService = new Mock<IConfigurationService>();
var employeeConfigurationService = new Mock<IEmployeeConfigurationService>();
var organizationConfigurationService = new Mock<IOrganizationConfigurationService>();
var facilityConfigurationService = new Mock<IFacilityConfigurationService>();
var configurationSettingService = new Mock<IConfigurationSettingService>();
// configure the dependencies so that the proper inputs are available
configurationService.Setup(x => x.GetByConfigurationNameAsync(It.IsAny<string>()))
.ReturnsAsync(GetConfigurations(true));
employeeConfigMapRepo.Setup(x => x.GetAllByEmployeeIdAsync(It.IsAny<int>()))
.ReturnsAsync(GetEmployeeConfigMaps(true));
employeeConfigurationService.Setup(x => x.GetAllByEmployeeIdAsync(It.IsAny<long>()))
.ReturnsAsync(GetEmployeeConfigMaps(true));
ruleRepo.Setup(x => x.GetByConfigurationIdAsync(It.IsAny<int>()))
.ReturnsAsync(GetRules(true));
ruleService.Setup(x => x.GetConfigRulesByEmployeeIdAsync(It.IsAny<long>(), It.IsAny<string>()))
.ReturnsAsync(GetRules(true));
// help the IOC do its thing, map interfaces to Mocked objects
unityContainer.RegisterInstance<IRuleService>(ruleService.Object);
unityContainer.RegisterInstance<IRuleRepo>(ruleRepo.Object);
unityContainer.RegisterInstance<IConfigurationService>(configurationService.Object);
unityContainer.RegisterInstance<IEmployeeConfigurationService>(employeeConfigurationService.Object);
unityContainer.RegisterInstance<IOrganizationConfigurationService>(organizationConfigurationService.Object);
unityContainer.RegisterInstance<IFacilityConfigurationService>(facilityConfigurationService.Object);
unityContainer.RegisterInstance<IConfigurationSettingService>(configurationSettingService.Object);
unityContainer.RegisterInstance<IRuleFacade>(ruleFacade.Object);
// thanks to all the mocking, the facade method ValidateEmployeeConfigurationAsync can now be tested properly
var ruleHelper = unityContainer.Resolve<RuleFacade>();
//ACT
var result = await
ruleHelper.ValidateEmployeeConfigurationAsync(employeeId, _testConfigName, configurationTypeId);
//ASSERT
Assert.IsNotNull(result);
Assert.AreEqual(true, result.PassedValidation);
}