web-dev-qa-db-ja.com

.NET Core Test Projectのappsettings json値を読み取ります

Webアプリケーションは、appsettings.jsonファイルからDocument DBキーを読み取る必要があります。キー名でクラスを作成し、ConfigureaServices()のConfigセクションを次のように読み取りました。

    public Startup(IHostingEnvironment env) {
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services) {
        services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
        services.AddSession();
        Helpers.GetConfigurationSettings(services, Configuration);
        DIBuilder.AddDependency(services, Configuration);
    }

テストプロジェクトのキー値を読み取る方法を探しています。

30
S.Siva

これはブログ投稿に基づいています。NET Coreユニットテストプロジェクトでの構成ファイルの使用(.NET Core 1.0向けに作成) 。

  1. 統合テストプロジェクトのルートディレクトリにappsettings.test.jsonを作成(またはコピー)し、プロパティで「ビルドアクション」をコンテンツとして指定し、「新しい場合はコピー」を出力ディレクトリに指定します。ファイル名を付けた方がよいことに注意してください(例:appsettings.test.json)通常とは異なるappsettings.json。同じ名前が使用される場合、メインプロジェクトのファイルがテストプロジェクトのファイルをオーバーライドする可能性があるためです。

  2. JSON構成ファイルNuGetパッケージ(Microsoft.Extensions.Configuration.Json)がまだ含まれていない場合は含めます。

  3. テストプロジェクトでメソッドを作成し、

    public static IConfiguration InitConfiguration()
            {
                var config = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.test.json")
                    .Build();
                    return config;
            }
    
  4. 通常どおり構成を使用する

    var config = InitConfiguration();
    var clientId = config["CLIENT_ID"]
    

ところで:。NET CoreのIOptions <>を使用した統合テスト

var options = config.Get<MySettings>();
46

正直なところ、単体テストアプリケーションの場合、他のクラスの呼び出し、ファイルシステム、データベース、ネットワークなどへのアクセスなど、すべての依存関係からテストしているクラスを分離する必要があります。テストまたは機能テスト。

そうは言っても、アプリケーションの単体テストを行うには、おそらくmock appsettings.jsonファイルのこれらの値を使用し、ロジックをテストするだけです。

したがって、_appsettings.json_は次のようになります。

_"DocumentDb": {
    "Key": "key1" 
} 
_

次に、設定クラスを作成します。

_public class DocumentDbSettings
{
    public string Key { get; set; }
}
_

次に、ConfigureServices()メソッドに登録します。

_services.Configure<DocumentDbSettings>(Configuration.GetSection("DocumentDb"));
_

たとえば、コントローラー/クラスは次のようになります。

_// ...
private readonly DocumentDbSettings _settings;

public HomeController(IOptions<DocumentDbSettings> settings)
{
    _settings = settings.Value;
}
// ...
public string TestMe()
{
    return $"processed_{_settings.Key}";
}
_

次に、テストプロジェクトで、このような単体テストクラスを作成できます。

_public class HomeControllerTests
{
    [Fact]
    public void TestMe_KeyShouldBeEqual_WhenKeyIsKey1()
    {
        // Arrange
        const string expectedValue = "processed_key1";
        var configMock = Substitute.For<IOptions<DocumentDbSettings>>();
        configMock.Value.Returns(new DocumentDbSettings
        {
            Key = "key1" // Mocking the value from your config
        });

        var c = new HomeController(configMock);

        // Act
        var result = c.TestMe();

        // Assert
        Assert.Equal(expectedValue, result);
    }
}
_

モックにはNSubstitute v2.0.0-rcを使用しました。

3
Ignas

の中に project.jsonテストプロジェクトから、次の依存関係を追加します。

"dependencies": {
  "xunit": "2.2.0-beta2-build3300",
  "Microsoft.AspNetCore.TestHost": "1.0.0",
  "dotnet-test-xunit": "2.2.0-preview2-build1029",
  "BancoSentencas": "1.0.0-*"
},

BancoSentencasは、テストするプロジェクトです。他のパッケージは、xUnitおよびメモリ内サーバーとなるTestHostからのものです。

Appsettings.jsonのこのビルドオプションも含めます。

"buildOptions": {
  "copyToOutput": {
    "include": [ "appsettings.Development.json" ]
  }
}

私のテストプロジェクトには、次のテストクラスがあります。

  public class ClasseControllerTeste : IClassFixture<TestServerFixture> {

    public ClasseControllerTeste(TestServerFixture fixture) {
      Fixture = fixture;
    }

    protected TestServerFixture Fixture { get; private set; }


    [Fact]
    public async void TestarRecuperarClassePorId() {
      using(var client = Fixture.Client) {
        var request = await Fixture.MyHttpRequestMessage(HttpMethod.Get, "/api/classe/1436");
        var response = await client.SendAsync(request);
        string obj = await response.Content.ReadAsStringAsync();
        ClasseModel classe = JsonConvert.DeserializeObject<ClasseModel>(obj);
        Assert.NotNull(classe);
        Assert.Equal(1436, classe.Id);
      }
    }
  }

また、インメモリサーバーを構成するTestServerFixtureクラスもあります。

  public class TestServerFixture : IDisposable {
    private TestServer testServer;
    protected TestServer TestServer {
      get {
        if (testServer == null)
          testServer = new TestServer(new WebHostBuilder().UseEnvironment("Development").UseStartup<Startup>());
        return testServer;
      }
    }

    protected SetCookieHeaderValue Cookie { get; set; }

    public HttpClient Client {
      get {
        return TestServer.CreateClient();
      }
    }

    public async Task<HttpRequestMessage> MyHttpRequestMessage(HttpMethod method, string requestUri) {      
      ...
      login stuff...
      ...
      Cookie = SetCookieHeaderValue.Parse(response.Headers.GetValues("Set-Cookie").First());

      var request = new HttpRequestMessage(method, requestUri);

      request.Headers.Add("Cookie", new CookieHeaderValue(Cookie.Name, Cookie.Value).ToString());
      request.Headers.Accept.ParseAdd("text/xml");
      request.Headers.AcceptCharset.ParseAdd("utf-8");
      return request;
    }

    public void Dispose() {
      if (testServer != null) {
        testServer.Dispose();
        testServer = null;
      }
    }
  }

それが私のプロジェクトのテスト方法です。メインプロジェクトのStartup.csを使用し、テストプロジェクト(appsettings.Development.json)のappsettings.jsonからコピーを作成します

2
Fabricio Koch

以下のように変更すると、Sudersonのソリューションが機能しました。

        var builder = new ConfigurationBuilder()
             .SetBasePath(Directory.GetCurrentDirectory())
             .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
             .AddEnvironmentVariables();

        IConfiguration config = builder.Build();

        //Now, You can use config.GetSection(key) to get the config entries
2
Bob

appSettings.jsonをテストプロジェクトのルートディレクトリにコピーし、そのプロパティをコンテンツおよび新しい場合はコピーとしてマークします。

var builder = new ConfigurationBuilder()
  .SetBasePath(Directory.GetCurrentDirectory())
  .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
  .AddEnvironmentVariables();
ConfigurationManager.Configuration = builder.Build();

ConfigurationManagerはクラスであり、静的プロパティConfigurationを持っています。これにより、アプリケーション全体がConfigurationManager.Configuration[<key>]としてアクセスできます。

WebApplicationFactory統合テスト用のテストサーバーを作成するため を使用していて、サーバー側コントローラーの設定値を取得する方法が既にある場合(おそらくそうです!)、次のように、統合テストでこれを再利用することができます(そして、必要な他の注入されたアイテムを取得できます)。

// Your test fixtures would be subclasses of this
public class IntegrationTestBase : IDisposable
{
    private readonly WebApplicationFactory<Startup> _factory;
    protected readonly HttpClient _client;

    // The same config class which would be injected into your server-side controllers
    protected readonly IMyConfigService _myConfigService;

    // Constructor (called by subclasses)
    protected IntegrationTestBase()
    {
        // this can refer to the actual live Startup class!
        _factory = new WebApplicationFactory<Startup>();
        _client = _factory.CreateClient();

        // fetch some useful objects from the injection service
        _myConfigService = (IMyConfigService)_factory.Server.Host.Services.GetService(typeof(IMyConfigService));
    }

    public virtual void Dispose()
    {
        _client.Dispose();
        _factory.Dispose();
    }
}

この場合、appsettings.jsonをコピーする必要はなく、(テスト)サーバーが使用しているのと同じappsettings.jsonを自動的に使用していることに注意してください。

0
Mike Beaton

ASP.NET Core 2.xプロジェクトの場合、appsettings.jsonファイルをビルドディレクトリに自動的に追加します。

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <None Include="..\MyProj\appsettings.json" CopyToOutputDirectory="PreserveNewest" />
  </ItemGroup>
</Project>
0
VahidN