我正在使用Autofac实现Xunit,我可以通过以下代码使其工作:
using (var scoped = DbFixture.Container.Resolve<UserReponsitory>())
{
var result = (scoped.GetAll()).ToList().Count();
Assert.Equal(2, result);
}
但我想将UserReponsitory注入测试方法而不是使用DbFixture.Container.Resolve
。是否可以使下面的代码工作?
的UnitTest1.cs
namespace XUnitTestPro
{
public class UnitTest1:IClassFixture<DbFixture>
{
private IUserReponsitory _userReponsitory;
public UnitTest1(IUserReponsitory userReponsitory)
{
_userReponsitory = userReponsitory;
}
[Fact]
public void Test1()
{
//using (var scoped = DbFixture.Container.Resolve<UserReponsitory>())
//{
// var result = (scoped.GetAll()).ToList().Count();
// Assert.Equal(2, result);
//}
var result = _userReponsitory.GetAll().ToList().Count();
Assert.Equal(2, result);
}
}
}
DbFixture.cs
namespace XUnitTestPro
{
public class DbFixture
{
public static IContainer Container { get; set; }
public DbFixture()
{
var builder = new ContainerBuilder();
var option = new DbContextOptionsBuilder<UserContext>().UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=EFProject;Trusted_Connection=True;MultipleActiveResultSets=true").Options;
UserContext context = new UserContext(option);
builder.RegisterInstance(context).As<UserContext>();
builder.RegisterType<UserReponsitory>().AsSelf().As<IUserReponsitory>();
builder.RegisterAssemblyTypes(typeof(DbFixture).GetTypeInfo().Assembly);
Container = builder.Build();
}
}
}
目前,我收到以下错误,似乎与IClassFixture<DbFixture>
有关,而public UnitTest1(IUserReponsitory userReponsitory)
则不同。
消息:以下构造函数参数没有匹配 夹具数据:IUserReponsitory userReponsitory
有没有办法在没有调用DbFixture.Container.Resolve
的情况下实现下面的代码,这类似于注入MVC控制器?
public UnitTest1(IUserReponsitory userReponsitory)
{
_userReponsitory = userReponsitory;
}
换句话说,我怎么能依赖注入单元测试类? 任何帮助将不胜感激。
答案 0 :(得分:1)
xUnit中的依赖注入支持有点受限。
当您实施IClassFixture<DbFixture>
接口时,xUnit在其构造函数中需要一个DbFixture
参数,并且参数的类型取决于{{1} } T
。
话虽如此,当你强迫IClassFixture<T>
时,你的构造函数必须看起来像IClassFixture<DbFixture>
。但是你有public UnitTest1(DbFixture)
,所以xUnit不知道在那里注入什么。
您还可以实现多种IUserRepository
类型,但每个测试类只能使用一次IClassFixture<T>
。
来自官方xUnit docs on shared context(T
):
重要提示:xUnit.net使用接口IClassFixture&lt;&gt;的存在要知道你想要创建和清理类夹具。无论是否将类的实例作为构造函数参数,它都会执行此操作。 Simiarly,如果添加构造函数参数但忘记添加接口,xUnit.net会告诉您它不知道如何满足构造函数参数。
仍然可以使用IoC容器解决它,而不是使用构造函数注入。
IClassFixture<T>
然而,问题是使用它的好方法呢?不确定您想要达到什么目标,但如果您想进行单元测试,那么您不必在所有或具体类别中使用IoC容器,只需要模拟和您正在测试的类型。
如果你想在ASP.NET Core MVC / WebApi上进行集成测试,那么你应该使用public class DbFixture
{
public IContainer Container { get; private set; }
public DbFixture()
{
var builder = new ContainerBuilder();
var option = new DbContextOptionsBuilder<UserContext>().UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=EFProject;Trusted_Connection=True;MultipleActiveResultSets=true").Options;
UserContext context = new UserContext(option);
builder.RegisterInstance(context).As<UserContext>();
builder.RegisterType<UserReponsitory>().AsSelf().As<IUserReponsitory>();
builder.RegisterAssemblyTypes(typeof(DbFixture).GetTypeInfo().Assembly);
Container = builder.Build();
}
}
public class UnitTest1:IClassFixture<DbFixture>
{
private IUserReponsitory _userReponsitory;
public UnitTest1(DbFixture fixture)
{
// resolve it here
_userReponsitory = fixture.Container.Resolve<IUserRepository>();
}
[Fact]
public void Test1()
{
//using (var scoped = DbFixture.Container.Resolve<UserReponsitory>())
//{
// var result = (scoped.GetAll()).ToList().Count();
// Assert.Equal(2, result);
//}
var result = _userReponsitory.GetAll().ToList().Count();
Assert.Equal(2, result);
}
}
类,它将整个应用程序与你已经配置的所有IoC一起旋转。
答案 1 :(得分:0)
如果你已经在单元测试中启用了构造函数注入,那么你几乎已经完成了。在测试的构造函数中,注入一个
Func<Owned<UserReponsitory>>
e.g。
namespace XUnitTestPro
{
public class UnitTest1:IClassFixture<DbFixture>
{
private Func<Owned<UserReponsitory>> _userRepositoryFactory;
public UnitTest1(Func<Owned<UserReponsitory>> userRepositoryFactory )
{
_userReponsitoryFactory = userReponsitoryFactory;
}
[Fact]
public void Test1()
{
//using (var scoped = DbFixture.Container.Resolve<UserReponsitory>())
//{
// var result = (scoped.GetAll()).ToList().Count();
// Assert.Equal(2, result);
//}
using (var scoped = userReponsitoryFactory())
{
var result = (scoped.Value.GetAll()).ToList().Count();
Assert.Equal(2, result);
}
}
}
}
Func是一个工厂,允许您返回自己的。拥有一个容器,允许您自己处理对象(使用块)