3

FakeIteasy CallTo アサーションで引数制約として式ツリーを使用できますか?

次のシグネチャを持つインターフェイスのメソッドを指定します。

interface IRepository<TEntity>
{
    TEntity Single(Expression<Func<TEntity, bool>> predicate);

次のようなコードで呼び出されます。

Flight flight = repository.Single(f => f.ID == id);

私は、次のような単体テストを念頭に置いています。

Expression<Func<Flight, bool>> myExpression = flight => flight.ID == 1;

A.CallTo(() => repository.Single(
                  A<Expression<Func<Flight, bool>>>.That.Matches(myExpression)))
                  .Returns(new Flight());

ただし、これにより警告が生成されます:型引数を明示的に指定してください

現在、理想的ではない Ignored プロパティを使用する必要があります。

4

3 に答える 3

3

「Matches」メソッドはラムダを取りますが、式に渡そうとしています。「Matches」コールで何を言おうとしていますか? あなたは平等に一致していますか?その場合、次のように記述します。

A.CallTo(() => repository.Single(myExpression)).Returns(new Flight());

式を何か他のものに制約したい場合は、タイプの述語を渡す必要があります: Func<Expression<Func<Flight, bool>>, bool>「Matches」メソッドに。

于 2011-09-29T19:12:04.553 に答える
2

ありがとう、パトリック、

つまり、式を解析し ( f => f.ID == id )、== の右側を実行してランタイム値を取得します。

コードでは、これは次のようになります。

A.CallTo(() => flightRepository.Single(A<Expression<Func<Flight, bool>>>.That
                .Matches(exp => Expression.Lambda<Func<int>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == 1)))
                .Returns(new Flight());

しかし、同じ目的を達成するためのよりエレガントな方法があるに違いないと考えずにはいられません。私はそれを別の日に残します。

ありがとう、マイケル・マクダウェル

于 2011-10-10T20:27:56.723 に答える
1

式を引数としてアサートしようとしたときに同じ問題が発生しましたが、Moq を使用していました。解決策はあなたにとってもうまくいくはずです...

私は同様の質問に対するこの回答にほとんどのクレジットを与えます: Moq Expect On IRepository Passing Expression

基本的に、式で ToString() を実行して比較できると言っています。ちょっとハックですが、欠点が 1 つだけあります。ラムダ式の変数名は一致する必要があります。

ここに例があります...

    [Test]
    public void TestWhichComparesExpressions()
    {
        // setup
        _mockRepository.Setup(x => x.GetByFilter(MatchQuery())).Returns(new List<Record>());

        // execute
        var records = _service.GetRecordsByFilter();

        // assert
        Assert.IsNotNull(records);
        Assert.AreEqual(0, records.Count());
    }

    private static Expression<Func<DomainRecord, bool>> MatchQuery()
    {
        return MatchExpression(ServiceClass.QueryForTheRecords); // constant
    }

    // https://stackoverflow.com/questions/288413/moq-expect-on-irepository-passing-expression/1120836#1120836
    private static Expression<Func<DomainRecord, bool>> MatchExpression(Expression<Func<DomainRecord, bool>> expression)
    {
        return It.Is<Expression<Func<DomainRecord, bool>>>(e => e.ToString() == expression.ToString());
    }

誰かがラムダ式の変数名を変更した場合、テストで同じになることを保証する、それを使用するクラスの定数に式を入れることにしました。

于 2011-11-21T22:17:35.510 に答える