我正在.NET Core中编写一些集成测试,我无法运行测试,因为连接字符串返回null。 Startup.cs
中的代码如下所示,我根据these answers将appsettings.json
复制到了测试项目中。我错过了什么?
编辑:我想出了如何逐步完成单元测试,即使我在测试中明确地将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;"
}
}
答案 0 :(得分:3)
我可能会抱怨生活在软件开发的最前沿,但我不会因为我正在从事个人项目。我在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类来初始化主机,但关键是使用&#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)
将NuGet包安装到您的测试项目,即 Microsoft.AspNetCore,Microsoft.EntityFrameworkCore.SqlServer和Microsoft.AspNetCore
将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);
....
}
}
答案 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>();