mardi 7 août 2018

How to properly test .net service logic

I have a functioning test but I need guidance how to properly test the logic. My understanding of testing is that it should be done without tight coupling to the resources (which is where mocking comes in) but if everything is mocked (especially the return result) how can the logic be tested, properly, without instantiating a bunch of classes?

ValidateEmployeeConfigurationAsync (below) will return RulesValidationResult which is what I want to assert. So I can answer my own question of how, which would require newing up repositories and services - that's one way. Is there a best practice way to accomplish that? That feels wrong.

Functioning Test

  [TestMethod]
  public async Task PassValidateEmployeeConfigurationTest()
  {
        //ARRANGE
        const long employeeId = 200L;
        const int configurationTypeId = (int) Constants.Configuration.ConfigurationTypes.User;
        const bool enabled = true;

        _ruleService = new Mock<IRuleService>();
        _configurationService = new Mock<IConfigurationService>();          
        _ruleFacade = new Mock<IRuleFacade>();

        _configurationService.Setup(x => x.GetByConfigurationNameAsync(It.IsAny<string>()))
            .ReturnsAsync(GetConfigurations(enabled));

        _ruleService.Setup(x => x.GetConfigRulesByEmployeeIdAsync(It.IsAny<long>()))
            .ReturnsAsync(GetRules(enabled));

        _ruleFacade.Setup(x =>
                x.ValidateEmployeeConfigurationAsync(It.IsAny<long>(), It.IsAny<string>(), It.IsAny<int>()))
            .ReturnsAsync(GetPassedValidationResult());

        //ACT
        var result = await
            _ruleFacade.Object.ValidateEmployeeConfigurationAsync(employeeId, "TestConfiguration", configurationTypeId);

        //ASSERT
        Assert.IsNotNull(result);
        Assert.AreEqual(true, result.PassedValidation);
  }

Method of interest

  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;

  }

Aucun commentaire:

Enregistrer un commentaire