测试类找不到连接字符串

时间:2016-08-21 00:44:56

标签: c# asp.net-core asp.net-core-mvc .net-core

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

编辑:我想出了如何逐步完成单元测试,即使我在测试中明确地将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;"
  }
}

6 个答案:

答案 0 :(得分:3)

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

  1. 整体解决方案文件夹为MyApi,其中src和test位于同一级别。
  2. 然后创建项目测试\ MyApi.IntegrationTests并将appsettings.json从src \ MyApi复制到test \ MyApi.IntegrationTests
  3. 然后您可以按如下方式创建测试:

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

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

答案 1 :(得分:2)

这对我有用

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

答案 2 :(得分:1)

  1. 将NuGet包安装到您的测试项目,即 Microsoft.AspNetCore,Microsoft.EntityFrameworkCore.SqlServer和Microsoft.AspNetCore

  2. 将appsettings.json文件复制并粘贴(或新)到您的测试项目包含..

  3. {
        "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);
    
        ....
    
       }
    }
    

答案 3 :(得分: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();

答案 4 :(得分:0)

在app项目中复制并粘贴appsettings.json,并确保在启动文件构造函数中包含以下代码。

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

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

答案 5 :(得分: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>();