2013-04-05 3 views
1

테스트에서 2 개의 Linq 표현식을 사용하려고합니다. Moq를 사용하고 콜백에서 테스트중인 메소드 내부에서 호출 된 표현식을 캡처합니다. 어설 실패 위에C#에서 람다 식과 ToString을 사용하여 비교하기

var siteCode = "site1"; 
var namePattern = "role1"; 
Expression<Func<Role, bool>> expectedExpression = 
        t => (string.IsNullOrEmpty(siteCode) 
          || t.Name.StartsWith(siteCode + "_") 
          || t.Name == siteCode) 
          && t.Name.Contains(namePattern); 
Assert.AreEqual(expectedExpression.ToString(), actualExpression.ToString()); 

:

Expression<Func<Role, bool>> actualExpression = null; 
roleRepositoryMock.Setup(t => t.Search(It.IsAny<Expression<Func<Role, bool>>>())) 
      .Callback((Expression<Func<Role, bool>> exp) => 
       { 
        actualExpression = exp; 
       }) 
      .Returns(new List<Role> { new Role { Name = "site1_code_role1", Description = "descr" }, new Role { Name = "site1_code" } }); 

나는 다음이 다음 방법을 비교한다. 문자열에 예상 된 표현과 같다 :

t => (((IsNullOrEmpty(value(BL.Tests.RolesServiceTests+<>c__DisplayClass6).siteCode) OrElse t.Name.StartsWith((value(BL.Tests.RolesServiceTests+<>c__DisplayClass6).siteCode + "_"))) OrElse (t.Name == value(BL.Tests.RolesServiceTests+<>c__DisplayClass6).siteCode)) AndAlso t.Name.Contains(value(BL.Tests.RolesServiceTests+<>c__DisplayClass6).namePattern)) 

그리고 실제 표현과 같다 :

t => (((IsNullOrEmpty(value(BL.Services.RolesService+<>c__DisplayClass3).site) OrElse t.Name.StartsWith((value(BL.Services.RolesService+<>c__DisplayClass3).site + "_"))) OrElse (t.Name == value(BL.Services.RolesService+<>c__DisplayClass3).site)) AndAlso t.Name.Contains(value(BL.Services.RolesService+<>c__DisplayClass3).pattern)) 

의 차이에 있습니다

  • C_ DisplayClass6와 C _DisplayClass3
  • BL.Services.RolesService 및 BL.Tests.RolesServiceTests (다른 네임 스페이스)

아무에게 설명하거나 왜 올바른 방향으로 나를 보낼 수 있습니까? 어떻게 해결할 수 있습니까? ToString()을 통해 이들을 비교하고 비교하는 것이 절대적으로 잘못된 방법 일 수 있습니까? 대안?

답변

0

구현 세부 사항과 결합되지 않고 코드 조각의 외부에서 관찰 가능한 동작을 확인하는 테스트를 작성하는 것이 좋습니다. 표현식을 문자열로 변환하면 테스트를 정확한 표현식뿐만 아니라 ToString 메소드 구현에 결합하게되며 이는 향후 .NET 버전에서 변경 될 수 있습니다.

더 나은 접근 방법은 일부 출력 상태를 설정하는 것입니다. 저장소에 전달 된 linq 표현식이 올바른 Role 컬렉션을 필터링하는지 확인하고자하는 것 같습니다. 이미 콜백을 통해 표현식을 캡처 할 수 있으므로이 표현식에 대해 몇 가지 테스트를 작성하십시오. Role 가정

Role 입력의 다른 그룹으로 표현 호출 테스트를 작성하고 정확한 출력이 발생되는 사소한 주장되어야하는 POCO이다. 표현식이 복잡하다면 당신은 많은 입력을해야 할 수도 있습니다,하지만 그것은 다음과 같이 보일 것입니다 :

var roles = new List<Role> 
{ 
    new Role { Name = siteCode+"_role1" }, 
    new Role { Name = siteCode+"_role22" }, 
    new Role { Name = siteCode+"_role1324" }, 
}; 

Assert.AreEqual(2, roles.Where(actualExpression.Compile()).Count()); //test the number of roles returned is as expected 

더 나은 여전히 ​​방법에 대한 지식을 갖는 시험없이 목적으로 만 클라이언트 코드의 인터페이스에서 테스트하는 것입니다 저장소가 쿼리됩니다.

+0

좋은 제안입니다. 나는 내가 표현을 실행하기 위해 객체 관계의 설정 (이 경우 객체 컬렉션이 될 것인가)을 벗어나려고했다. –

관련 문제