我正在.NET Core中编写一些集成测试,我无法运行测试,因为连接字符串返回null。我在Startup.cs
的代码如下,我根据appsettings.json
将these answers复制到测试项目中。我错过了什么?
编辑:我想出了如何逐步完成单元测试,并且环境被设置为生产,即使我在测试和主要项目中明确地将ASPNETCORE_ENVIRONMENT
设置为development
。我正在调试模式下构建。我不知道我应该在哪里设置这个。无论哪种方式,它应该拉入一个值而不是null - appsettings.development.json
和appsettings.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;"
}
}
我可能会抱怨生活在软件开发的最前沿,但我不会因为我只是在做个人项目。我在API项目(引用实体框架)中没有设置关于连接字符串的相同症状,所以这里的示例MyAPI项目对我有用。
然后您可以按如下方式创建测试:
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中调试测试,所以为了奖励,它是:测试 - >调试 - >选定的测试|所有测试
这对我有用
var builder = new WebHostBuilder()
.UseStartup<Startup>()
.UseSetting("ConnectionStrings:DefaultConnection", /*Your conn string*/)
{
"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);
....
}
}
我有同样的问题并通过首先将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();
将您的appsettings.json复制并粘贴到Test项目中,并确保您的Startup文件构造函数中包含以下代码。
public Startup(IConfiguration configuration)
{
// Configuration = configuration;
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
}
我在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>();