简体   繁体   English

使用AutoFixture对HTML Helper进行单元测试

[英]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. 首先,调用InjectCreateAnonymous的组合是很惯用的-特别是如果您颠倒顺序。 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.

相关问题 辅助类和单元测试 - Helper Classes and Unit Testing C#如何使用AutoFixture简化单元测试字符串参数 - C# How to simplify unit testing string parameters using AutoFixture 在使用Moq和AutoFixture进行单元测试API时模拟HttpResponseMessage - Mock HttpResponseMessage while unit testing API with Moq and AutoFixture 如何简化单元测试DDD值对象与AutoFixture相等 - How to simplify Unit Testing DDD Value objects Equality with AutoFixture 使用 AutoFixture 中的 AutoMock 对构造函数中的反应式代码进行单元测试? - Unit testing Reactive code in constructors using AutoMock from AutoFixture? AutoFixture AutoDataAttribute的单元测试中的ArgumentNullException - ArgumentNullException in a unit test for AutoFixture AutoDataAttribute 如何从单元测试中排除名称中带有“Test”的辅助项目? - How to exclude helper projects with “Test” in their name from unit testing? 依赖注入和单元测试 - 静态辅助方法或私有实例方法 - dependecy injection and unit testing - static helper methods or private instance methods 单元测试:绕过或模拟调用静态电子邮件助手 - Unit testing: bypass or mock call to static email helper 如何使用 XUnit、Moq 和 AutoFixture 对控制器进行单元测试? - How to unit test a controller with XUnit, Moq and AutoFixture?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM