Domanda

Sto cercando di unit test un Helper HTML usando AutoFixture. Qui di seguito è il mio 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));
}

Come si può vedere solo restituisce una stringa MVC HTML con tag da tavolo e Id collegato ad esso. (Vedi sotto conseguenza Unità test per un esempio)

Prova Unità con 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 e FakeViewDataContainer sono solo le implementazioni di falsi HttpContextBase e IViewDataContainer.

Questo test passa e restituisce il risultato atteso. Tuttavia, I ‘m non sono sicuro io sono correttamente utilizzando l'Autofixture qui. C'è un modo migliore per utilizzare AutoFixture all'interno di questa unità di prova?

È stato utile?

Soluzione

Sulla base di informazioni parziali è difficile dire esattamente come il test di cui sopra potrebbe essere ulteriormente ridotto, ma direi che potrebbe essere ridotta.

Prima di tutto, la combinazione di invocare Inject seguito da CreateAnonymous è piuttosto idiomatica - in particolare se si inverte la sequenza. Questo si chiama congelamento il valore anonimo (ed è equivalente a un contenitore di DI portata vita Singleton). Si può affermare più succintamente in questo modo:

var vc = fixture.Freeze<ViewContext>();

Sembra anche come se il test è mappatura HttpContext a FakeHttpContext. Mapping si può fare un po 'più facile , ma che sarà map Transient casi ...

In ogni caso, se non avete motivi validi per utilizzare Manuale Mocks invece di un dinamica Mock biblioteca , si potrebbe anche decidere di utilizzare AutoFixture come un auto -mocking contenitore . Che potrebbe liberarsi di voi un sacco di che tipo di mappatura.

Quindi, dato tutto questo, mi piacerebbe indovinare che si può essere in grado di ridurre il test per qualcosa di simile:

[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);
}

Tuttavia, la maggior parte della parte Disporre ora è puramente dichiarativa, e dal momento che ti sembra di essere già utilizzando xUnit.net, è possibile utilizzare Teorie Autodata per AutoFixture per spostare la maggior parte delle variabili di argomenti di metodo:

[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);
}

Questo presuppone che hai colmato l'AutoMoqCustomization con l'AutoDataAttribute in questo modo:

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute :
        base(new Fixture().Customize(new AutoMoqCustomization()))
    { }
}

Si prega di tenere presente che potrebbe essere necessario modificare il codice di cui sopra un po 'per adattarlo i dettagli della vostra API. Questo è inteso solo come uno schizzo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top