4

AutoFixtureを使用して、WebApiサイトのコントローラーをテストしようとしています。Ploehのブログに記載されているように、私は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.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

1 に答える 1

6

これは、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クラスに注意してください-これでうまくいくはずです。

カスタマイズの順序が重要であることに注意してください。

于 2012-09-26T17:13:51.050 に答える