2012-09-26 113 views
4

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

我的控制器在构造函数中需要一个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.GetCallsManagerCorrectly: 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 
} 

它通过,但后来我失去了让控制器自动建立起来,仍然是确定的,如果我添加参数构造函数的能力。

回答

4

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

而不是如博客文章中所述实现[AutoMoqData]属性,我建议创建一个稍微不同的属性和定制 - 一组基本上将作为整个单元测试项目的一组约定。我总是这样做,而且我总是竭尽全力为一个单元测试项目提供一套约定。一套约定帮助我保持我的测试(和SUT)一致。

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

+0

感谢您的快速和正确的回应。很棒。 –

+0

@BrianMcCord和其他人很确定上面的'HttpSchemeCustomization'现在是AF V3 +中的固有功能。 –