2013-10-07 44 views
2

我是在模仿新的,我試圖做到這一點模擬例如:爲什麼與Expression <Func<T,bool>的這個模擬不匹配?

Repository.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.Ge tForExpression(It.IsAny >>()))。Returns(new List());

但我想使用更具體的標準,這只是一個例子,我做證明我需要什麼。

這個例子不匹配,任何人都可以幫助理解爲什麼並解決這個問題嗎?

回答

0

如果需要測試代表我通常把它們應用到任何測試對象。 爲了測試PersonService,我寧願使用包含兩個測試示例的以下代碼。

[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(); 
    } 
} 
0

表達式是沒有可比性,因此==將返回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

0

表達式不能像那樣進行比較。如果你想匹配表達式的細節,你需要把表達式傳遞給你的模擬並解析它的樹(如this answer所述)。結果會是這個樣子(其中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)); 
} 
相關問題