[英]Unit Testing an Html Helper with AutoFixture
I'm attempting to Unit Test an Html Helper using AutoFixture. 我正在尝试使用AutoFixture对HTML助手进行单元测试。 Below is my SUT 下面是我的SUT
public static MvcHtmlString SampleTable(this HtmlHelper helper,
SampleModel model, IDictionary<string, object> htmlAttributes)
{
if (helper == null)
{
throw new ArgumentNullException("helper");
}
if (model == null)
{
throw new ArgumentNullException("model");
}
TagBuilder tagBuilder = new TagBuilder("table");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.GenerateId(helper.ViewContext.HttpContext.Items[Keys.SomeKey].ToString());
return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
}
As you can see it just returns an MVC Html string with table tags and Id attached to it. 如您所见,它只是返回带有表标签和ID的MVC Html字符串。 (See below Unit Test result for an example) (有关示例,请参见下面的单元测试结果)
Unit Test with AutoFixture: 使用AutoFixture进行单元测试:
[Fact]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
{
var fixture = new Fixture();
//Arrange
fixture.Inject<HttpContextBase>(new FakeHttpContext());
var httpContext = fixture.CreateAnonymous<HttpContextBase>();
fixture.Inject<ViewContext>(new ViewContext());
var vc = fixture.CreateAnonymous<ViewContext>();
vc.HttpContext = httpContext;
vc.HttpContext.Items.Add(Keys.SomeKey, "foo");
fixture.Inject<IViewDataContainer>(new FakeViewDataContainer());
var htmlHelper = fixture.CreateAnonymous<HtmlHelper>();
var sampleModel = fixture.CreateAnonymous<SampleModel>();
//Act
var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();
//Assert
Assert.Equal("<table id=\"foo\"></table>", result);
}
FakeHttpContext and FakeViewDataContainer are just the fake implementations of HttpContextBase and IViewDataContainer. FakeHttpContext和FakeViewDataContainer只是HttpContextBase和IViewDataContainer的虚假实现。
This test passes and returns the expected result. 该测试通过并返回预期结果。 However, I 'm not sure I'm correctly utilizing the Autofixture here. 但是,我不确定我在这里是否正确使用了Autofixture。 Is there a better way to use AutoFixture within this Unit Test? 在此单元测试中,有没有更好的方法使用AutoFixture?
Based on partial information it's hard to tell exactly how the above test could be further reduced, but I would guess that it could be reduced. 根据部分信息,很难确切说明如何进一步减少上述测试,但是我想可以将其减少。
First of all, the combo of invoking Inject
followed by CreateAnonymous
is rather idiomatic - particularly if you reverse the sequence. 首先,调用Inject
和CreateAnonymous
的组合是很惯用的-特别是如果您颠倒顺序。 This is called Freezing the anonymous value (and is equivalent to a DI container's Singleton lifetime scope). 这称为冻结匿名值(相当于DI容器的Singleton生存期作用域)。 It can be stated more succinctly like this: 可以这样更简洁地说:
var vc = fixture.Freeze<ViewContext>();
It also seems as though the test is mapping HttpContext to FakeHttpContext. 似乎测试也正在将HttpContext映射到FakeHttpContext。 Mapping can be done a little bit easier , but that'll map Transient instances... 映射可以稍微容易一些 ,但这将映射Transient实例...
In any case, unless you have compelling reasons to use Manual Mocks instead of a dynamic Mock library , you might as well decide to use AutoFixture as an auto-mocking container . 在任何情况下,除非有令人信服的理由使用“ 手动装箱”而不是动态“ 装箱” 库 ,否则您最好决定将AutoFixture用作自动装箱容器 。 That might rid you of a lot of that type mapping. 这可能会让您摆脱很多类型映射。
So, given all that, I'd guess that you might be able to reduce the test to something like this: 因此,考虑到这一切,我猜 ,你也许能测试减少是这样的:
[Fact]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
//Arrange
var vc = fixture.Freeze<ViewContext>();
vc.HttpContext.Items.Add(Keys.SomeKey, "foo");
var htmlHelper = fixture.CreateAnonymous<HtmlHelper>();
var sampleModel = fixture.CreateAnonymous<SampleModel>();
//Act
var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();
//Assert
Assert.Equal("<table id=\"foo\"></table>", result);
}
However, most of the Arrange part is now purely declarative, and since you seem to already be using xUnit.net, you can use AutoData Theories for AutoFixture to move most of the variables to method arguments: 但是,大多数Arrange部分现在仅是声明性的,并且由于您似乎已经在使用xUnit.net,因此可以使用AutoData的AutoFixture理论将大多数变量移至方法参数:
[Theory, AutoMoqData]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml(
[Frozen]ViewContext vc,
HtmlHelper htmlHelper,
SampleModel sampleModel)
{
//Arrange
vc.HttpContext.Items.Add(Keys.SomeKey, "foo");
//Act
var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();
//Assert
Assert.Equal("<table id=\"foo\"></table>", result);
}
This assumes that you've bridged the AutoMoqCustomization with the AutoDataAttribute like this: 假设您已经将AutoMoqCustomization与AutoDataAttribute桥接在一起,如下所示:
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute :
base(new Fixture().Customize(new AutoMoqCustomization()))
{ }
}
Please keep in mind that you may need to tweak the above code a bit to make it fit the details of your API. 请记住,您可能需要稍微调整上面的代码,以使其适合您API的详细信息。 This is only meant as a sketch. 这仅是草图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.