我的Visual Studio 2017项目包含一些单元测试项目。所有这些测试都针对一个ASP.NET核心服务器运行。我希望在所有测试之前启动ASP.NET核心服务器一次,并在所有测试之后将其关闭。
我的主要测试项目包含一个用于启动测试服务器的类:
public class TestServer : IDisposable
{
public static string Url { get { return "http://localhost:44391/"; } }
private static string GetApplicationPath()
{
return Path.GetFullPath(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "..", "..", "..", "..", "..", "..", "src", "MyProject"));
}
public IWebHost BuildHost()
{
var config = new ConfigurationBuilder()
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseEnvironment("UnitTests")
.UseKestrel()
.UseUrls(TestServer.Url)
.UseContentRoot(GetApplicationPath())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
return host;
}
private IWebHost _testserver;
public TestServer()
{
_testserver = BuildHost();
_testserver.Start();
}
#region IDisposable
~TestServer()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
bool _IsDisposed = false;
protected virtual void Dispose(bool disposeManagedResources)
{
if (this._IsDisposed)
return;
if (disposeManagedResources)
{
_testserver.Dispose();
}
this._IsDisposed = true;
}
#endregion
}
为了启动测试服务器,我添加了这个帮助程序类:
public static class TestServerStaticHelper
{
static object LockServer = new object();
static int ServerCount = 0;
static TestServer _service;
public static void Attach()
{
lock (LockServer)
{
ServerCount++;
if (_service == null)
_service = new TestServer();
}
}
public static void Detach()
{
lock (LockServer)
{
ServerCount--;
if (ServerCount <= 0 && _service != null)
{
_service.Dispose();
_service = null;
}
}
}
}
我从包含[AssemblyInitialize()]
和[AssemblyCleanup()]
[TestClass]
public class TestServerFixture
{
[AssemblyInitialize()]
public static void AssemblyInit(TestContext context)
{
TestServerStaticHelper.Attach();
}
[AssemblyCleanup()]
public static void AssemblyCleanup()
{
TestServerStaticHelper.Detach();
}
}
这对我的主要测试组件非常有效。但是如果我添加另一个带有测试的程序集,包含用于Assembly-Init和Cleanup的TestServerFixture,它们将不会共享该服务。相反,Visual Studio测试将尝试两次启动服务。
我猜每个包含测试的项目/程序集都是在一个单独的应用程序域中启动的?
如何在多个测试程序集之间共享静态服务器/服务?