【问题标题】:Autofixture and WebApi ControllerAutofixture 和 WebApi 控制器
【发布时间】:2012-09-18 07:54:51
【问题描述】:

我正在使用 AutoFixture 尝试为 WebApi 站点测试我的控制器。如Ploeh's blog 所述,我正在使用带有 Moq 的 AutoData 功能。

我的控制器在构造函数中使用了一个 IDepartmentManager。这是我的测试:

[Theory, AutoMoqData]
public void GetCallsManagerCorrectly(
    [Frozen]Mock<IDepartmentManager> departmentManagerMock,
    DepartmentsController sut)
{
    // Fixture setup
    // Exercise system
    sut.Get();
    // Verify outcome
    departmentManagerMock.Verify(d => d.GetAllDepartments(), Times.Exactly(1));
    // Teardown
}

当我运行此测试时,它会失败并显示以下内容:

GetCallsManagerCorrectly 失败了:
System.InvalidOperationException : 抛出异常,而 获取理论数据 Provision.Tests.WebApiControllerTests.DepartmentControllerTests.GetCallsManager 正确: System.Reflection.TargetInvocationException:已引发异常 通过调用的目标。 ---> System.ArgumentException:仅 允许使用“http”和“https”方案。参数名称:值在 System.Net.Http.HttpRequestMessage.set_RequestUri(Uri值)

首先,这仍然是编写这些测试的有效且推荐的方式吗?我喜欢它使一切变得多么小。

其次,我应该怎么做才能解决这个问题?如果我将测试更改为:

[Theory, AutoMoqData]
public void GetCallsManagerCorrectly(
    [Frozen]Mock<IDepartmentManager> departmentManagerMock)
{
    // Fixture setup
    DepartmentsController sut =
        new DepartmentsController(departmentManagerMock.Object);
    // Exercise system
    sut.Get();
    // Verify outcome
    departmentManagerMock.Verify(d => d.GetAllDepartments(), Times.Exactly(1));
    // Teardown
}

它通过了,但是我失去了自动构建控制器的能力,如果我向构造函数添加参数仍然可以。

【问题讨论】:

    标签: unit-testing asp.net-web-api moq xunit autofixture


    【解决方案1】:

    这绝对是使用 AutoFixture 编写测试的推荐方式。这个问题很容易解决。

    我建议不要像博客文章中描述的那样实现 [AutoMoqData] 属性,而是创建一个稍微不同的属性和自定义 - 一组基本上将作为整个单元测试项目的一组约定。我总是这样做,而且我总是竭尽全力为单个单元测试项目设置一组约定。一组约定可以帮助我保持测试(和SUTs)的一致性。

    public class AutoMyWebApiDataAttribute : AutoDataAttribute
    {
        public AutoMyWebApiDataAttribute()
            : base(new Fixture().Customize(new MyWebApiCustomization()))
        {
        }
    }
    

    MyWebApiCustomization 可以这样定义:

    public class MyWebApiCustomization : CompositeCustomization
    {
        public MyWebApiCustomization()
            : base(
                new HttpSchemeCustomization(),
                new AutoMoqCustomization(),
            )
        {
        }
    
        private class HttpSchemeCustomization : ICustomization
        {
            public void Customize(IFixture fixture)
            {
                fixture.Inject(new UriScheme("http"));
            }
        }
    }
    

    注意额外的 HttpSchemeCustomization 类 - 这应该可以解决问题。

    请注意the order of Customizations matters

    【讨论】:

    • @BrianMcCord 和其他人 可以肯定的是,上面的 HttpSchemeCustomization 现在是 AF V3+ 中固有的。
    猜你喜欢
    • 2012-12-12
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多