2014-02-12 3 views
11

LogTrace (문자열 값, params 객체 [] 매개 변수)가있는 ILogger 인터페이스가 있습니다. 이제 LogTrace가 호출되고 로그 할 문자열에 ID가 있는지 확인하려고합니다. 문제는 다른 방식으로 호출 될 수 있다는 것입니다. 예 : 1) LogTrace ("MyString"+ id) 2) LogTrace ("MyString {0}", id) 등등.moq를 사용하여 매개 변수 매개 변수가있는 함수에 대한 호출 확인

Moq이 모든 시나리오를 확인하는 좋은 방법이 있습니까? 나는 검증을 위해 사용할 수있는 문자열을 포맷 할 손으로 만든 모의 (mock)를 만드는 것에 대해서만 생각할 수 있습니다.

답변

1

당신은 Callback 사용하려고 할 수 있지만 (테스트하지)가 상당히 복잡 얻을 : ILogger 작은 인터페이스를 가지고

var mock = new Mock<ILogger>(); 
string trace = null; 
mock.Setup(l => l.LogTrace(It.IsAny<string>(), It.IsAny<object[]>())) 
     .Callback((s1, par) => 
      { 
       trace = string.Format(s1, par); 
      }); 

//rest of the test 

Assert.AreEqual(expected, trace); 

경우, 수동으로 스텁 구현을 고려해 볼 수 있습니다 (즉, 모든 라인을 유지하는 것 로그를 기록해야 함) 테스트가 끝날 때이를 확인합니다. 여러 행을 기록한 경우이 값보다 읽기 쉬운 설정이됩니다. 그냥 어떻게 든 배열과 일치 할 수 있도록

+0

항상 한 번만 호출되는 것은 아니기 때문에 더욱 복잡해졌으며 확인해야합니다. 나는 이제 막 내 매개 변수가 이드와 같은지 테스트했지만이 목적을 위해 내 스텁을 작성하려고합니다. –

10
mock.Verify(m => m.LogTrace(It.IsAny<string>(), It.IsAny<object[]>())); 

params object[] (예 : 위와 같이,이 아무것도 허용) 어쨌든 object[] 같은 방법으로 전달됩니다.

mock.Verify(m => m.LogTrace(It.IsAny<string>(), 
      It.Is<object[]>(ps => 
       ps != null && 
       ps.Length == 1 && 
       ps[0] is int && 
       (int)ps[0] == 5 
      ))); 

이 예는 PARAM 목록이 비어 있지 않은 경우 확인하는 방법과 같은 5을 포함

당신이 목록을 더 세밀하게 제어해야 할 경우, 당신은 당신의 자신의 조건을 만들 수있는 It.Is 정규 표현을 사용 형식이 int 인 유일한 매개 변수입니다.

+0

어쨌든 전달되었습니다.하지만이 방법은 내가 원하는 ID를 포함했는지 알 수 없습니다. 거기서 볼 수 있습니다. –

+0

@IlyaChernomordik : 내 대답을 편집했습니다. –

+0

이것은 지금 내가 한 일이지만, 로깅 방법이 ID를 매개 변수로 전달하지만 "Id ="+ 5와 같은 일을하면 도움이되지 않습니다. 단지 덜 깨지기 쉽도록하려고했습니다. –

1

여기에 필요한 것을 쉽게 할 수있는 방법이 없다고 생각합니다.이

  • 문자열 을 포함 통과 -

    • 문자열 ID를 포함 및 매개 변수 ID가 포함 문제는 당신이 값의 특정 조합은 여러 가지 검증 시나리오 결과 당신의 방법에 전달 될 수 있도록 할 필요가있다 ID 및 매개 변수 ID가 포함되어 있지 않습니다 - ID를 포함하지 않는
    • 문자열을 전달 및 매개 변수 ID가 포함 = ID를 포함하지 않는 ID 및 매개 변수를 포함하지 않는
    • 문자열을 통과 - 실패

    그러나 Moq는 검증 가능한 방법의 여러 인수간에 이러한 종류의 조건식을 지원하지 않습니다. 가능한 한 가지 해결책은 어느 한 인수에 존재 이없는 대신 ID가없는이 있는지 확인하는 것입니다. 같은 시도 :

    mock.Verify(m => m.LogTrace(
        It.Is<string>(s => !s.Contains(id)), 
        It.Is<object[]>(o => !o.Contains(id))), Times.Never()); 
    

    우리가 여기서하고있는 것은 조건이 만난되어 실패 여부를 확인한다 - 즉, 귀하의 문자열이 ID를 포함하지 않는, 그리고 어느 개체의 배열을한다. 우리는 Times.Never()를 사용하여 이러한 상황이 발생하지 않도록합니다.

    그러나 언뜻보기에는 코드가 명확하지 않을 수 있습니다. 일단 당신이 그것을 쓰면 당신의 의도를 적절하게 설명하는지 확인하십시오.

  • +0

    이것은 흥미로운 제안이지만 로깅이 2 번 호출되는 것을 확인하는 것은 어렵습니다. –

    +0

    이것은이 어설 션 전후에 메소드가 호출되는지 확인하기위한 다른 Verify()를 포함하는 것입니다. LogTrace를 몇 번 호출했는지에 관계없이이 테스트는 기록 된 문자열에 항상 ID가 포함되도록해야합니다. 메소드가 적어도 한 번 호출되었는지 확인하기 위해 실제로 추가 어설 션을 작성해야합니다. – rla4

    관련 문제