大佬教程收集整理的这篇文章主要介绍了XUnit 依赖注入,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
现在的开发中越来越看重依赖注入的思想,微软的 Asp.Net Core 框架更是天然集成了依赖注入,那么在单元测试中如何使用依赖注入呢?
本文主要介绍如何通过 XUnit 来实现依赖注入, XUnit 主要借助 SharedContext 来共享一部分资源包括这些资源的创建以及释放。
针对 Scoped 的对象可以借助 XUnit 中的 IClassFixture 来实现
@H_489_12@IDisposable
接口IClassFixture<Fixture>
针对 Singleton 的对象可以借助 XUnit 中的 ICollectionFixture 来实现
@H_489_12@Fixture
,需要初始化的资源在构造方法里初始化,如果需要在测试结束的时候释放资源需要实现 IDisposable
接口ICollectionFixture<Fixture>
,并@L_874_8@一个 [CollectionDeFinition("CollectionName")]
Attribute,CollectionName
需要在整个测试中唯一,不能出现重复的 CollectionName
[Collection("CollectionName")]
Attribute,然后在构造方法中注入对应的 Fixture
[Collection("CollectionName")]
Attribute,其他类只需要集成这个基类就可以了这里直接以 XUnit 的示例为例:
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new sqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public sqlConnection Db { get; private set; }
}
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture fixture;
public MyDatabaseTests(DatabaseFixture fixturE)
{
this.fixture = fixture;
}
[Fact]
public async Task Gettest()
{
// ... write tests,using fixture.Db to get access to the sql Server ...
// ... 在这里使用注入 的 DatabaseFixture
}
}
这里以一个对 asp.net core API 的测试为例
@H_489_12@/// <sumMary>
/// Shared Context https://xunit.github.io/docs/shared-context.html
/// </sumMary>
public class APITestFixture : IDisposable
{
private readonly IWebHost _server;
public IserviceProvider services { get; }
public httpClient Client { get; }
public APITestFixture()
{
var baseUrl = $"http://localhost:{GetRandomPort()}";
_server = WebHost.CreateDefaultBuilder()
.UseUrls(baseUrl)
.UseStartup<TestStartup>()
.build();
_server.Start();
services = _server.services;
Client = new httpClient(new WeihanLi.Common.http.NoProxyhttpClientHandler())
{
BaseAddress = new Uri($"{BaseUrl}")
};
// Add Api-Version Header
// Client.DefaultrequestHeaders.TryAddWithoutValidation("Api-Version","1.2");
Initialize();
Console.WriteLine("test begin");
}
/// <sumMary>
/// TestDataInitialize
/// </sumMary>
private void Initialize()
{
}
public void Dispose()
{
using (var dbContext = services.Getrequiredservice<ReservationDbContext>())
{
if (dbContext.Database.IsInMemory())
{
dbContext.Database.Ensuredeleted();
}
}
Client.Dispose();
_server.Dispose();
Console.WriteLine("test end");
}
private static int GetRandomPort()
{
var random = new Random();
var randomPort = random.Next(10000,65535);
while (IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners().Any(p => p.port == randomPort))
{
randomPort = random.Next(10000,65535);
}
return randomPort;
}
}
[CollectionDeFinition("APITESTCollection")]
public class APITESTCollection : ICollectionFixture<APITestFixture>
{
}
[CollectionDeFinition("TESTCollection")]
public class TESTCollection : ICollectionFixture<TestStartupFixture>
{
}
[Collection("APITESTCollection")]
public class ControllerTESTBase
{
protected httpClient Client { get; }
protected IserviceProvider services { get; }
public ControllerTESTBase(APITestFixture fixturE)
{
Client = fixture.Client;
services = fixture.services;
}
}
public class NoticeControllerTest : ControllerTESTBase
{
public NoticeControllerTest(APITestFixture fixturE) : base(fixturE)
{
}
[Fact]
public async Task GetNoticeList()
{
using (var response = await Client.GetAsync("/api/notice"))
{
Assert.Equal(httpStatusCode.oK,response.StatusCodE);
var responseString = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<PagedListModel<Notice>>(responseString);
Assert.NotNull(result);
}
}
[Fact]
public async Task GetNoticeDetails()
{
var path = "test-notice";
using (var response = await Client.GetAsync($"/api/notice/{path}"))
{
Assert.Equal(httpStatusCode.oK,response.StatusCodE);
var responseString = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<Notice>(responseString);
Assert.NotNull(result);
Assert.Equal(path,result.NoticeCustomPath);
}
}
[Fact]
public async Task GetNoticeDetails_NotFound()
{
using (var response = await Client.GetAsync("/api/notice/test-notice1212"))
{
Assert.Equal(httpStatusCode.NotFound,response.StatusCodE);
}
}
}
运行测试,查看我们的 APITestFixture
是不是只实例化了一次,查看输出日志:
可以看到我们输出的日志只有一次,说明在整个测试过程中确实只实例化了一次,只会启动一个 web server,确实是单例的
@H_920_119@memo微软推荐的是用 @H_363_14@microsoft.AspNetCore.Mvc.TesTing 组件去测试 Controller,但是个人感觉不如自己直接去写web 服务去测试,如果没必要引入自己不熟悉的组件最好还是不要去引入新的东西,否则可能就真的是踩坑不止了。
以上是大佬教程为你收集整理的XUnit 依赖注入全部内容,希望文章能够帮你解决XUnit 依赖注入所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。