3

私はモックが初めてで、このモックの例を実行しようとしています:

リポジトリ.cs

public class Repository : IRepository
{
    public List<Person> GetForExpression(Expression<Func<Person,bool>> expression  )
    {
        ... //get person from orm using expression
    }
}

PersonService.cs

public class PersonService
{
    private IRepository _repository;
    public PersonService(IRepository repository)
    {
        _repository = repository;
    }

    public List<Person> GetAllPersonsWith18More()
    {            
        var result = _repository.GetForExpression(x => x.Age > 18);

        return result;

    }
}

テスト:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var moqRepository = new Mock<IRepository>();
        var service = new PersonService(moqRepository.Object);
        Expression<Func<Person, bool>> criteria = y => y.Age  18;
        moqRepository.Setup(x => x.GetForExpression(It.Is<Expression<Func<Person, bool>>>(y => y == criteria))).Returns(new List<Person>());
        service.GetAllPersonsWith18More();
        moqRepository.VerifyAll();
    }
}

このセットアップを使用すると動作します: moqRepository.Setup(x => x.GetForExpression(It.IsAny>>())).Returns(new List());

しかし、より具体的な基準を使用したいのですが、これは必要なものを示すために行う一例にすぎません。

この例は一致しません。理由を理解し、この問題を解決できる人はいますか?

4

3 に答える 3

2

デリゲートをテストする必要がある場合は、通常、それらを任意のテスト オブジェクトに適用します。PersonService をテストするには、2 つのテストの例を含む次のコードを使用します。

[TestClass]
public class UnitTest2
{
    private Mock<IRepository> moqRepository;
    private PersonService service;

    [TestInitialize]
    public void TestInitialize()
    {
        moqRepository = new Mock<IRepository>();
        service = new PersonService(moqRepository.Object);
    }

    [TestMethod]
    public void TestMethod3()
    {
        // arrange
        var persons = new List<Person>
        {
            new Person { Age = 0 },
            new Person { Age = 1 },
            new Person { Age = 17 },
            new Person { Age = 18 },
            new Person { Age = 19 },
            new Person { Age = 100 }
        };
        moqRepository
            .Setup(x => x.GetForExpression(It.IsAny<Expression<Func<Person, bool>>>()))
            .Returns<Expression<Func<Person, bool>>>(expr => persons.Where(expr.Compile()).ToList());

        // act
        var result = service.GetAllPersonsWith18More();

        // assert
        moqRepository.VerifyAll();
        result.Should().BeEquivalentTo(persons.Where(x => x.Age > 18));
    }

    [TestMethod]
    public void TestMethod4()
    {
        // arrange
        Expression<Func<Person, bool>> criteria = x => x.Age > 18;
        moqRepository
            .Setup(x => x.GetForExpression(It.IsAny<Expression<Func<Person, bool>>>()))
            .Returns(new List<Person>())
            .Callback<Expression<Func<Person, bool>>>(expr =>
            {
                var persons = new List<Person>
                {
                    new Person { Age = 0 },
                    new Person { Age = 1 },
                    new Person { Age = 17 },
                    new Person { Age = 18 },
                    new Person { Age = 19 },
                    new Person { Age = 100 }
                };
                persons.Where(expr.Compile()).Should().BeEquivalentTo(persons.Where(criteria.Compile()));
            });

        // act
        service.GetAllPersonsWith18More();

        // assert
        moqRepository.VerifyAll();
    }
}
于 2013-10-07T19:42:22.753 に答える
0

式はそのように比較することはできません。式を非常に詳細に一致させたい場合は、モックに渡された式を取得し、そのツリーを解析する必要があります (この回答で概説されているように)。結果は次のようになります (FuncTest.FuncEqual前の回答で見つけることができます)。

moqRepository
    .Setup(x => x.GetForExpression(ExpressionMatches(criteria))
    .Returns(new List<Person>());

// ...

public static Expression<Func<TSource, TValue>> ExpressionMatches(Expression<Func<TSource, TValue>> expr)
{
    return Match.Create<Expression<Func<TSource, TValue>>(actualExpr => FuncTest.FuncEqual(expr, actualExpr));
}
于 2013-10-07T14:08:32.900 に答える
-1

式は比較できないため、式ツリーが完全に一致する場合でも == は false を返します。

int criteria = 5;
Expression<Func<int, bool>> criteria1 = y => y == criteria;
Expression<Func<int, bool>> criteria2 = y => y == criteria;
System.Diagnostics.Debug.WriteLine(criteria1 == criteria2); // false

回避策として、expression.ToString() を呼び出して文字列表現を比較できます: Comparing Simple Lambda Expressions With Moq .

于 2013-10-07T14:01:40.667 に答える