我正在写这篇文章是因为我已经尝试了一下,以解决自己的问题。无论出于何种原因,我都能找到的每个示例似乎都表明这是开箱即用的,但是每当我尝试执行相同操作时,总是会出错。基本上,我有一个具有两个属性的控制器,它们是通过注入的。 DI,比方说
public class SomeController
{
private ISomeInterface _i;
private MyConfig _c;
public SomeController(ISomeInterface i, MyConfigContext cxt) // Where cxt is Type of DbContext
{
_i = i;
_c = cxt.Configs.FirstOrDefault();
}
public OkResult PostModel(SomeModel c)
{
// Do things
return Ok();
}
}
在使用xUnit,Moq和AutoFixture的测试中,我试图避免手动实例化依赖项B
和C
:
public class SomeControllerTests
{
private MyDbContext _cxt;
private Fixture _fixture;
public SomeControllerTests()
{
_cxt = GetCxt() // GetCxt() just returns a context instance, nothing special
_fixture = new Fixture();
_fixture.Customize(new AutoMoqCustomization { ConfigureMembers = true });
_fixture.Customizations.Add(
new TypeRelay(
typeof(ISomeInterface),
typeof(SomeConcreteClass)
)
);
}
[Fact, AutoData]
public void PostStatus_ReturnsOk_GivenValidRequest()
{
SomeController c = _fixture.Create<SomeController>();
SomeModel m = _fixture.Create<SomeModel>();
var result = c.PostModel(m);
Asset.IsType<OkResult>(result);
}
}
使用上面的方法,我在运行测试时得到NotImplementedException
,并且它不会告诉我确切的未实现的内容,因此我无法知道问题所在。我必须在文档中缺少某些内容。我想使用AutoFixture使测试更持久,但到目前为止,尝试使用它一直很痛苦。我真的不想只为了运行测试而手动模拟/存根整个应用程序。理想情况下,我想使用AutoFixture文档中显示的语法,其中将与测试相关的实例放在测试的参数中,它们是为您创建的,但是我没有运气,例如... >
[Theory, AutoData]
SomeTestMethod(SomeController c, SomeModel m)
{
var result = c.PostModel(m);
Assert.IsType<OkResult>(result);
}
感谢您的阅读(:
答案 0 :(得分:0)
我认为这里发生了两件事。
首先,我假设您的控制器继承自ControllerBase。 Autofixture似乎无法创建ControllerContext,您可以通过在安装过程中注入一个实例来解决此问题。
[Theory, AutoData]
SomeTestMethod(SomeController c, SomeModel m)
第二部分与此结构的测试有关
public class ControllerAutoDataAttribute : AutoDataAttribute
{
public ControllerAutoDataAttribute() : base(() =>
{
var fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
fixture.Customizations.Add(
new TypeRelay(
typeof(ISomeInterface),
typeof(SomeConcreteClass)
)
);
fixture.Inject(new ControllerContext());
return fixture;
}){ }
}
将在调用SomeControllerTests()构造函数之前构造注入的类型(SomeController和SomeModel)。这意味着夹具定制为时已晚。解决方法是创建一个自定义AutoDataAttribute,然后将自定义移到那里,就像这样:
[Theory, ControllerAutoData]
SomeTestMethod(SomeController c, SomeModel m)
{
var result = c.PostModel(m);
Assert.IsType<OkResult>(result);
}
然后更改您的测试方法以像这样使用它:
{{1}}
答案 1 :(得分:0)
尝试添加下一个属性并使用它代替AutoData
。
using AutoFixture.AutoMoq;
using AutoFixture.Xunit2;
namespace Cats
{
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(() => new Fixture().Customize(new AutoMoqCustomization()))
{
}
}
}
[Theory, AutoMoqData]
SomeTestMethod(SomeController c, SomeModel m)
{
var result = c.PostModel(m);
Assert.IsType<OkResult>(result);
}