問題

特定の名前空間内のクラスをチェックするテストを作成したいと思います。任意の種類のリストを返すクラスのすべてのメソッドは、nullを返す場合はチェックする必要があります。もしそうなら、テストは失敗する必要があります。

クラス/メソッド自体には依存関係(コンストラクタ引数とメソッドパラメータ)もあり、自動化する必要があります。

AutoFixtureは、任意の種類のリストを返すメソッドがnullを返さないことを確認するメカニズムを持っていますか?

クラスの例:

 public class UserService
{
    private readonly IRemotingFacade _remotingFacade;

    public UserService(IRemotingFacade remotingFacade)
    {
        _remotingFacade = remotingFacade;
    }

    // directly return a list
    public IEnumerable<User> GetUsers()
    {

    }

    // directly return a list, pass method parameters
    public IEnumerable<User> GetUsers(string filter)
    {

    }

    // wrapped list
    public IBusinessResponse<IEnumerable<User>> GetUsers()
    {

    }


    // wrapped list, pass method parameters
    public IBusinessResponse<IEnumerable<User>> GetUsers(string filter)
    {

    }
}
 

したがって、リストを別のオブジェクト内でラップできるようにしてください。

  ベストアンサー

AutoFixture 3.18.0は、 Idioms.FsCheck という新しい接着剤ライブラリを導入し、 FsCheck を使用して再利用可能な アサーション名は ReturnValueMustNotBeNullAssertion です。

この新しいアサーションは、値(Query)を返すメソッドがnullを返さないことを検証します。

インストール

Idioms.FsCheckはNuGetで利用できます:

 PM> Install-Package AutoFixture.Idioms.FsCheck
 

シナリオ

UserServiceIRemotingFacadeの注入インスタンスを使用し、2つの[1]クエリを公開します。

  • ユーザー[] GetUsers()
  • ユーザー[] GetUsers(int)

シナリオ#1:IRemotingFacadeの注入されたインスタンスはnullを返します。

 [Theory, UnitTestConventions]
public void Scenario1(
    ISpecimenBuilder builder,
    [Frozen]Mock<IRemotingFacade> stub)
{
    stub.Setup(x => x.GetUsers()).Returns((User[])null);

    var sut = from x in new Methods<UserService>() select x.GetUsers();

    var assertion = new ReturnValueMustNotBeNullAssertion(builder);
    Assert.Throws<ReturnValueMustNotBeNullException>(() =>
        assertion.Verify(sut));
}
 

シナリオ#2:IRemotingFacadeの注入されたインスタンスはnullを返しません:

 [Theory, UnitTestConventions]
public void Scenario2(
    ISpecimenBuilder builder,
    [Frozen]Mock<IRemotingFacade> stub,
    User[] users)
{
    stub.Setup(x => x.GetUsers()).Returns(users);

    var sut = from x in new Methods<UserService>() select x.GetUsers();

    var assertion = new ReturnValueMustNotBeNullAssertion(builder);
    Assert.DoesNotThrow(() => assertion.Verify(sut));
}
 

シナリオ3:iが-1 GetUsers(int)の場合、nullが返されます。

 [Theory, UnitTestConventions]
public void Scenario3(
    ISpecimenBuilder builder,
    [Frozen]Mock<IRemotingFacade> stub,
    User[] users)
{
    stub.Setup(x => x.GetUsers()).Returns(users);

    var sut = from x in new Methods<UserService>() 
              select x.GetUsers(default(int));

    var assertion = new ReturnValueMustNotBeNullAssertion(builder);
    Assert.Throws<ReturnValueMustNotBeNullException>(
        () => assertion.Verify(sut));
}
 

備考

F#3.1だけがをインストールしている場合は、app.configファイルにアセンブリバインディングリダイレクトを追加することもできます。

 <dependentAssembly>
  <assemblyIdentity name="FSharp.Core" 
                    publicKeyToken="b03f5f7f11d50a3a" 
                    culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" 
                   newVersion="4.3.1.0" />
</dependentAssembly>
 

UnitTestConventionsAttributeは次のように定義されます。

 internal class UnitTestConventionsAttribute : AutoDataAttribute
{
    internal UnitTestConventionsAttribute()
        : base(new Fixture().Customize(new AutoMoqCustomization()))
    {
    }
}
 

リフレクションクエリは Albedo で実行されます。


[1]デモのために、私は以下のように元のコードを簡略化しました:

 public class User
{
}

public interface IRemotingFacade
{
    User[] GetUsers();
}

public class UserService
{
    private readonly IRemotingFacade remotingFacade;

    public UserService(IRemotingFacade remotingFacade)
    {
        if (remotingFacade == null)
            throw new ArgumentNullException("remotingFacade");

        this.remotingFacade = remotingFacade;
    }

    public User[] GetUsers()
    {
        return this.remotingFacade.GetUsers();
    }

    public User[] GetUsers(int i)
    {
        if (i == -1)
            return null;

        return this.remotingFacade.GetUsers();
    }
}
 

  同じタグがついた質問を見る

c#unit-testingautofixture