Как да инжектирам конфигурационни настройки в тестови класове (ASP.NET Core)?

SmtpConfig съдържа моите идентификационни данни, които искам да използвам в тестов клас. appsettings.development.json

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "SmtpConfig": {
    "credentials": "username:password"
  }
}

Тук конфигурирам smtpConfig да бъде инжектиран в класове (в класовете на контролера работи много добре!) Startup.cs

public IConfigurationRoot Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
      services.AddMvc();

      services.Configure<SmtpConfig(
         Configuration.GetSection(nameof(SmtpConfig)
      ));
}

Искам да получа достъп до идентификационни данни от appsettings.development.json в тестове, защото на друг сървър ще имам друг конфигурационен файл.

//important usings
using Microsoft.Extensions.Options;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
    public class SomeControllerAPITest
    {
       private SmtpConfig _smtpConfig;

        public SomeControllerAPITest(IOptions<SmtpConfig> smtpConfig)
        {
            _smtpConfig = smtpConfig.Value;
        }


        [TestMethod]
        public void Post_ReturnsCreatedInstance()
        {
            var credentials = _smtpConfig.credentials;

            //use that credentials
            ...

            //call remote server
            ...
        }
}

Възможно ли е да се направи това?


person Alex    schedule 05.07.2017    source източник


Отговори (2)


- Създайте клас файл в testProject

public static IConfiguration getConfig(){ 
   var config = new ConfigurationBuilder() 
     .SetBasePath("/Users/Project/")
     .AddJsonFile("appsettings.json")  
     .Build(); 
   return config; 
}

    [TestClass]
    public class TestMasterClass
    {
        public static IConfiguration _configuration { get; set; }

        public TestMasterClass()
        {
            _configuration = AnotherClassFile.getConfig();
        }

        [TestMethod]
        public void TestConfigElasticSearch()
        {

            var elasticSearch = _configuration["ElasticSearchConfig:Link01"];
            Assert.IsNotNull(elasticSearch);
        }
    }
person Jonathan Troncoso    schedule 10.07.2018
comment
Този отговор може да бъде подобрен с обяснение какво прави вашият код, за да разреши зададения въпрос. - person Greg the Incredulous; 10.07.2018

Можете да използвате същата Microsoft.Extensions.Configuration обвързваща функционалност, за да създадете идентично попълнен IOptions<TConfiguration> екземпляр. Ето груб еквивалент на това как внедрихме това за нашия тестов код:

public class TestSmtpConfigOptions : IOptions<SmtpConfig> {

    private static Lazy<SmtpConfig> configuration { get; }

    static TestSmtpConfigOptions() {
        configuration = new Lazy<SmtpConfig>(GetConfiguration);
    }

    public SmtpConfig Value {
        get { return configuration.Value; }
    }

    private static SmtpConfig GetConfiguration() {
        var configuration = new SmtpConfig();
        var path = Path.Combine("config", "appsettings.development.json");

        new ConfigurationBuilder()
            .SetBasePath("path/to/base/directory/of/project")
            .AddJsonFile(path, optional: true)
            .Build()
            .GetSection(nameof(SmtpConfig))
            .Bind(configuration);

        return configuration;
    }

}

След това, във вашето устройство, трябва само да го инстанциирате:

[TestClass]
public class SomeControllerAPITest {

    private SmtpConfig _smtpConfig;

    public SomeControllerAPITest() {
        _smtpConfig = new TestSmtpConfigOptions().Value;
    }


    [TestMethod]
    public void Post_ReturnsCreatedInstance() {
        var credentials = _smtpConfig.credentials;

        //use that credentials
        ...

        //call remote server
        ...
    }
}

В случай, че се интересувате от кръстосани платформени пътища и нямате нищо против малко допълнителна сложност, ето малък клас, който използваме, за да получим основния път по междуплатформен начин за нашия xUnit тестов инструмент. Това означава, че използваме TestConfiguration.BasePath вместо "path/to/base/directory/of/project" в горния пример.

internal static class TestConfiguration {

    internal static string BasePath { get; }

    static TestConfiguration() {
        BasePath = Environment.GetEnvironmentVariable("BASE_DIRECTORY");

        if (BasePath == null) {
            BasePath = AppContext.BaseDirectory;

            // cross-platform equivalent of "../../../../../"
            for (var index = 0; index < 5; index++) {
                BasePath = Directory.GetParent(BasePath).FullName;
            }
        }
    }

    internal static string ResolvePath(string relativePath) {
        return Path.Combine(BasePath, relativePath);
    }

}
person Technetium    schedule 30.10.2017