Xunit项目中的依赖注入
Posted
技术标签:
【中文标题】Xunit项目中的依赖注入【英文标题】:Dependency injection in Xunit project 【发布时间】:2018-06-19 06:12:23 【问题描述】:我正在开发一个 ASP.Net Core MVC Web 应用程序。
我的解决方案包含 2 个项目:
一个用于应用程序和 第二个项目,专门用于单元测试 (XUnit)。我在 Tests 项目中添加了对应用程序项目的引用。
我现在要做的是在 XUnit Tests 项目中编写一个类,它将通过实体框架与数据库进行通信。
我在应用程序项目中所做的是通过构造函数依赖注入来访问我的DbContext
类。
但我不能在我的测试项目中这样做,因为我没有 Startup.cs
文件。在这个文件中,我可以声明哪些服务可用。
那么我该怎么做才能在测试类中获得对我的DbContext
实例的引用?
【问题讨论】:
试试 xunit 框架中内置的 xunit di 支持:nuget.org/packages/Xunit.Di,这样您就可以像对任何其他应用程序一样注入服务依赖项。 【参考方案1】:您可以实现自己的服务提供者来解析DbContext
。
public class DbFixture
public DbFixture()
var serviceCollection = new ServiceCollection();
serviceCollection
.AddDbContext<SomeContext>(options => options.UseSqlServer("connection string"),
ServiceLifetime.Transient);
ServiceProvider = serviceCollection.BuildServiceProvider();
public ServiceProvider ServiceProvider get; private set;
public class UnitTest1:IClassFixture<DbFixture>
private ServiceProvider _serviceProvider;
public UnitTest1(DbFixture fixture)
_serviceProvider = fixture.ServiceProvider;
[Fact]
public void Test1()
using (var context = _serviceProvider.GetService<SomeContext>())
但请记住,在单元测试中使用 EF 并不是一个好主意,最好模拟 DbContext。
The Anatomy of Good Unit Testing
【讨论】:
什么是 DatabaseSeeder ?我应该将 DbFixture 放在 Service 子文件夹中吗? 哎呀复制粘贴错误。您可以将DbFixture
放在测试项目中的任何位置。我创建TestSetup
或TestInfrastructure
文件夹并将这些类放在这些文件夹中。
我使用的是这个,而不是你的 AddEntityFrameworkSqlServer 行:serviceCollection.AddDbContextAddEntityFrameworkSqlServer
注册了额外的服务。
@Matt 我修复了断开的链接。【参考方案2】:
您可以使用Xunit.DependencyInjection
【讨论】:
扩展它的作用以及为什么它比其他方法更好在这里会非常有用。另外添加一个小样本来展示它在使用时的外观会很棒。 ***.com/questions/63269460/… 解决问题【参考方案3】:对于单元测试,您需要模拟您的上下文。
有一个很棒的用于模拟的 nuget 包,称为 Moq。
一些帮助您入门:
public ClassName : IDisposable
private SomeClassRepository _repository;
private Mock<DbSet<SomeClass>> _mockSomeClass;
public ClassName()
_mockSomeClass = new Mock<DbSet<SomeClass>>();
var mockContext = new Mock<IApplicationDbContext>();
mockContext.SetupGet(c => c.SomeClass).Returns(_mockSomeClass.Object);
_repository = new SomeClassRepository(mockContext.Object);
public void Dispose()
// Anything you need to dispose
[Fact]
public void SomeClassTest()
var someClass = new SomeClass() // Initilize object ;
_mockSomeClass.SetSource(new[] someClass );
var result = _repository.GetSomethingFromRepo( ... );
// Assert the result
对于集成测试,你做同样的事情,但设置是:
_context = new ApplicationDbContext();
确保您的 TestClass
继承自 IDisposable
(TestClass : IDisposable
),以便您可以在每次测试后处理上下文。
https://xunit.github.io/docs/shared-context
【讨论】:
xunit 中没有设置,属性。改用构造函数。【参考方案4】:您可以使用包 Microsoft.EntityFrameworkCore.InMemory
var _dbContextOptions = new DbContextOptionsBuilder<DbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
然后
var context = new DbContext(_dbContextOptions);
【讨论】:
以上是关于Xunit项目中的依赖注入的主要内容,如果未能解决你的问题,请参考以下文章