【问题标题】:need to create convention for ApiControllers需要为 ApiControllers 创建约定
【发布时间】:2013-12-22 04:56:11
【问题描述】:

我在测试中有一组有效的命令式代码,我正在尝试将其归结为基本的测试约定。

我的测试如下所示:

[Theory, BasicConventions]
public void GetVersionOnSiteVersionControllerReturnsASiteVersion(IFixture fixture)
{
    fixture.OmitAutoProperties = true;
    SiteVersion expected = fixture.Create<SiteVersion>();
    SiteVersion actual = null;

    var sut = fixture.Create<SiteVersionController>();

    var response = sut
        .GetSiteVersion()
        .ExecuteAsync(new CancellationToken())
        .Result
        .TryGetContentValue<SiteVersion>(out actual);

    actual.AsSource().OfLikeness<SiteVersion>().ShouldEqual(expected);
}

我还进行了一项自定义设置以使其正常工作,即将HttpConfigurationHttpRequestMessage 设置为默认的非空值。

public class ApiControllerCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        var origin = fixture.OmitAutoProperties;
        fixture.OmitAutoProperties = true;
        var sut = fixture.Create<SiteVersionController>();
        sut.Configuration = fixture.Create<HttpConfiguration>();
        sut.Request = fixture.Create<HttpRequestMessage>();
        fixture.Inject<SiteVersionController>(sut);
        fixture.OmitAutoProperties = origin;
    }
}

首先,这看起来很难看,但如果我使用 Build().omit().with(config).with(request),它会关闭构建这些实例所需的 automoq 自定义。

其次,这仅适用于 SiteVersionController。我宁愿为我所有的 ApiControllers 概括这一点(也许这是个坏主意,但我要等我尝试后才能知道)。

基本上我的约定如下: 对于所有 ApiControllers,创建它们时不使用自动属性,但将 http 配置和请求消息属性设置为默认的非空值

【问题讨论】:

  • 您在使用什么ApiController 类型? ASP.NET Web API?哪个版本?
  • 我的 NuGet 包管理器说 ASP.NET Web API 版本 5.0.0

标签: c# autofixture


【解决方案1】:

ApiControllers 很难连接起来,因为您需要为它们分配某些属性才能使一切正常工作。至少,您需要分配Request 属性,否则Controller 无法调用Request.CreateResponse。因此,关闭ApiController 实例的自动属性并不是一个好策略。相反,您可以配置 AutoFixture 以正确连接 HttpRequestMessage 实例。

网络 API 1

对于 ASP.NET Web API 1,我通常使用这样的自定义:

public class WebApiCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customize<HttpRequestMessage>(c => c
            .Do(x =>
                x.Properties.Add(
                    HttpPropertyKeys.HttpConfigurationKey,
                    new HttpConfiguration())));
    }
}

由于默认情况下启用自动属性,这将分配一个适当的 HttpRequestMessage 实例给 ApiController.Request。与 Auto-mocking 自定义一起,Fixture 现在可以创建所有 ApiController 类的实例。

网络 API 2

使用 ASP.NET Web API 2 (5.0.0.0),事情会稍微复杂一些,但经过一些反复试验,我得到了这个自定义以通过 808 测试:

public class WebApiCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customize<HttpConfiguration>(c => c
            .OmitAutoProperties());
        fixture.Customize<HttpRequestMessage>(c => c
            .Do(x =>
                x.Properties.Add(
                    HttpPropertyKeys.HttpConfigurationKey,
                    fixture.Create<HttpConfiguration>())));
        fixture.Customize<HttpRequestContext>(c => c
            .Without(x => x.ClientCertificate));
    }
}

约定

如果您将其打包到 [AutoData] 属性中,您应该能够将您的测试重构为:

[Theory, BasicConventions]
public void GetVersionOnSiteVersionControllerReturnsASiteVersion(
    SiteVersionController sut,
    SiteVersion expected)
{
    SiteVersion actual = null;

    var response = sut
        .GetSiteVersion()
        .ExecuteAsync(new CancellationToken())
        .Result
        .TryGetContentValue<SiteVersion>(out actual);

    actual.AsSource().OfLikeness<SiteVersion>().ShouldEqual(expected);
}

【讨论】:

  • 这很棒。问题,谢天谢地,我掌握了 AutoFixture 的窍门,我的大多数挂断都试图连接这样的东西。你如何着手研究这个,一个策略?还是只是体验?
  • 好吧,就个人而言,我写了 AutoFixture,所以你可以说我在作弊:) 我也邀请其他人回答这个问题。
  • 在 F# 中对 ASP.NET Web API 2 的相同自定义可以在以下位置找到:gist.github.com/moodmosaic/2789ba06980880217df7
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 2014-03-11
  • 2021-03-12
  • 2012-07-02
  • 1970-01-01
  • 2019-11-18
  • 1970-01-01
相关资源
最近更新 更多