测试类找不到连接字符串

问题描述 投票:2回答:6

我正在.NET Core中编写一些集成测试,我无法运行测试,因为连接字符串返回null。我在Startup.cs的代码如下,我根据appsettings.jsonthese answers复制到测试项目中。我错过了什么?

编辑:我想出了如何逐步完成单元测试,并且环境被设置为生产,即使我在测试和主要项目中明确地将ASPNETCORE_ENVIRONMENT设置为development。我正在调试模式下构建。我不知道我应该在哪里设置这个。无论哪种方式,它应该拉入一个值而不是null - appsettings.development.jsonappsettings.production.json都有一个字符串,而通用的appsettings.json低于(与开发相同)。

编辑2:测试项目似乎完全忽略了我设置的任何配置。它正在运行主项目的Startup,无论我是否告诉它。我删除了对它的所有引用,它仍然试图运行它。

Startup.cs

public IConfigurationRoot Configuration { get; }

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", true, true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
        .AddEnvironmentVariables();

    Configuration = builder.Build();
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MyContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("MyDatabase")));
}

appsettings.json

{
  "ConnectionStrings": {
    "MyDatabase": "Server=localhost;Database=MyDevLocal;Trusted_Connection=True;"
  }
}
c# asp.net-core asp.net-core-mvc .net-core
6个回答
3
投票

我可能会抱怨生活在软件开发的最前沿,但我不会因为我只是在做个人项目。我在API项目(引用实体框架)中没有设置关于连接字符串的相同症状,所以这里的示例MyAPI项目对我有用。

  1. 整体解决方案文件夹为MyApi,其中src和test在同一级别内。
  2. 然后创建项目测试\ MyApi.IntegrationTests并将appsettings.json从src \ MyApi复制到test \ MyApi.IntegrationTests

然后您可以按如下方式创建测试:

using System;
using System.Threading.Tasks;
using Xunit;
using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.Hosting;
using System.Text;
using System.Net.Http;
using System.Net;
using Newtonsoft.Json;
using System.IO;

namespace Tests
{
    public class MyAPIRequestsShould
    {
        IWebHostBuilder _webHostBuilder;
        TestServer _host;
        HttpClient _client;

        public MyAPIRequestsShould()
        {
            string curDir = Directory.GetCurrentDirectory();
            _webHostBuilder = new WebHostBuilder().UseContentRoot(curDir).UseStartup<MyApi.Startup>();
            _host = new TestServer(_webHostBuilder);
            _client = _host.CreateClient();
        }

    private dynamic newTestRegistration(string mobileCountryCode = "44", string fullMobile = "447900123456", string firstName = "Scooby", string surname = "Doo", DateTime? registeredAt = null)
    {
        return new { mobileCountryCode = mobileCountryCode, fullMobile = fullMobile, firstName = firstName, surname = surname, registeredAt = (registeredAt == null ? DateTime.UtcNow : (DateTime)registeredAt) };
    }

        [Fact]
        public async Task Return422WhenCountryCodeTooLong() 
        {
            object requestData = newTestRegistration(mobileCountryCode);
            var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json");
            // Exercise the fluent validation
            var response = await _client.PostAsync("api/appusers/registration", content);
            Assert.Equal(422, (int) response.StatusCode);
        }
    }
}

我正在使用MyApi的Startup类初始化主机,但关键是在测试构造函数中使用'UseContentRoot(curDir)'。在此之前,env.ContentRoot设置为某个bin文件夹。现在它找到了appsettings.json文件的测试版本,我喜欢这样一个事实,即我可以通过更改连接字符串将其指向我的数据库的集成版本。

我不知道如何从Visual Studio中调试测试,所以为了奖励,它是:测试 - >调试 - >选定的测试|所有测试


2
投票

这对我有用

var builder = new WebHostBuilder() .UseStartup<Startup>() .UseSetting("ConnectionStrings:DefaultConnection", /*Your conn string*/)


1
投票
  1. 将NuGet包安装到测试项目,即Microsoft.AspNetCore,Microsoft.EntityFrameworkCore.SqlServer和Microsoft.AspNetCore
  2. 复制并粘贴(或新)appsettings.json文件到您的测试项目包含..
{
    "ConnectionStrings": {
        "YourConnection": "Data Source=.\\SqlExpress;Initial Catalog=DatabaseName;Integrated Security=True;"
    }
}
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

    public class YourTestServicesShould
    {
        private YourContext _yourContext; //TODO DI
        public IConfigurationRoot Configuration { get; set; }
        [Fact]
        public void Save_WhenGivenAValidOrderItem()
        {
            //Arrange
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            Configuration = builder.Build();

            var optionsBuilder = new DbContextOptionsBuilder<_yourContext>();
            optionsBuilder.UseSqlServer(Configuration.GetConnectionString("YourConnection"));
            _yourContext= new YourContext(optionsBuilder.Options);

    ....

   }
}

0
投票

我有同样的问题并通过首先将appsettings.json文件复制到我的测试项目并将输出设置为always copy来实现它。然后在我的测试设置中,我做了以下事情:

 string curDir = Directory.GetCurrentDirectory();

        var builder = new ConfigurationBuilder()
            .SetBasePath(curDir)
            .AddJsonFile("appsettings.json");

        var webBuilder = new WebHostBuilder()
            .UseContentRoot(curDir).UseConfiguration(builder.Build())
            .UseStartup<Startup>();


        var server = new TestServer(webBuilder);

        _client = server.CreateClient();

0
投票

将您的appsettings.json复制并粘贴到Test项目中,并确保您的Startup文件构造函数中包含以下代码。

public Startup(IConfiguration configuration)
        {
           // Configuration = configuration;

            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json");
                Configuration = builder.Build();
        }

0
投票

我在Asp .Net Core 2.2中有类似的问题我在Visual Studio中执行测试并且缺少配置文件。显然我需要设置appsettings的路径,但UseContentRoot()不适合我。我的解决方案是:

var configuration = new ConfigurationBuilder()
  .AddJsonFile(appSettingsPath)
  .Build();

var builder = new WebHostBuilder()
  .UseConfiguration(configuration)
  .UseStartup<Web.Startup>();
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.