10

/방법을 기다리고, 내가 비주얼 스튜디오를 사용하고 단위 테스트 코드 커버리지를 기다리고 우리는 비동기 방식이 있다고 가정 2013비동기/비동기에 대한 단위 테스트를 작성하는 방법

: 내가 사용하고 있기 때문에

public async Task DoSomethingAsync() 
{ 
    ... 
    await _service.DoInternalAsync(); 
    ... 
} 

을 비주얼 스튜디오의 최신 버전, 그것은 비동기 방식의 단위 테스트에 좋은 지원이 있습니다

: 기본적으로

[TestMethod] 
public async Task DoSomthingAsyncTest() 
{ 
    ... 
    await _objectUnderTest.DoSomethingAsync(); 
    // how to verify the result??? here is what I did 
    _service.Verify(_ => _.DoInternalAsync()); 
} 

을, 나는이 개 질문이

  1. 코드에 설명 된대로 Task 결과를 확인하는 방법은 무엇입니까? 나는 그 일을 올바르게 했는가?
  2. 해당 테스트를 실행하면 VS에서 테스트 통과라고 표시됩니다. 하지만 코드 커버 리지를 확인할 때, await _service.DoInternalAsync() 문장은 코드 커버리지 결과의 관점에서 보지 못했고, MoveNext() 문장은 6 개의 커버 블록을 가지고 있습니다. 그 안에 무엇이 잘못 되었습니까?
+4

을 작업보다는 다른 아무것도 반환하지 않는'async' 방법 때문에, 단순히 Service''당신의 모의가 호출 된 것을 주장한다. 다른 것을 테스트 할 필요가 없으며,'service' 클래스 내의 유닛 테스트는 이미 그것의 행동을 다룹니다. 반환 값이 있다면 비동기 메서드로 클래스를 모의 할 수있는 방법이 있습니다. –

답변

8

필자의 연구에서 코드 커버리지 문제는 최신 버전 Visual Studio 2013의 Visual Studio 버그로 다음 주요 버전에서 수정/향상 될 것입니다. feedback에서

인용구 :

당신이보고있는 문제는 우리가 아직 코드 커버리지의 비동기/await를 패턴에 대한 완벽한 지원이없는 때문에되는 우리의 끝에서 버그 때문입니다. 이 작업은 보류 중이며 다음 주요 업데이트/릴리스에서 제공해야합니다. 이 문제에 대한 해결 방법은 없습니다.

+1

공식적인 의견을 보내 주셔서 감사합니다. – Emile

2

코드가 적용되지 않는 이유는 비동기 메서드가 구현되는 방식과 관련이 있습니다. C# 컴파일러는 실제로 비동기 메서드의 코드를 상태 시스템을 구현하는 클래스로 변환하고 원래 메서드를 해당 상태 시스템을 초기화하고 호출하는 스텁으로 변환합니다. 이 코드는 어셈블리에서 생성되므로 코드 범위 분석에 포함됩니다.

코드가 처리되는 시점에 완료되지 않은 작업을 사용하는 경우 컴파일러에서 생성 한 상태 시스템은 완료 콜백을 연결하여 작업 완료시 다시 시작합니다. 이는 상태 시스템 코드를보다 완전하게 연습하여 완전한 코드 커버리지를 제공합니다 (최소한 명령문 수준 코드 커버리지 도구의 경우).

현재 완료되지 않은 작업을 수행하는 일반적인 방법이 있지만 일부 시점에서는 완료됩니다. 단원 테스트에서 Task.Delay를 사용하는 것입니다. 그러나 시간 지연은 너무 작기 때문에 (테스트가 실행되기 전에 작업이 완료되기 때문에 예측할 수없는 코드 범위가 발생하기 때문에) 또는 너무 커서 (테스트를 불필요하게 느려지 게하기 때문에) 일반적으로 좋지 않은 옵션입니다.

더 나은 옵션은 "await Task.Yield()"를 사용하는 것입니다. 이렇게하면 즉시 반환되지만 설정이 완료되면 즉시 연결을 호출합니다.

또 다른 옵션은 다소 불합리하지만 연속 콜백이 연결될 때까지보고가 완료되지 않고 즉시 완료된다는 의미의 패턴을 구현하는 것입니다. 이것은 기본적으로 상태 머신을 비동기 경로로 강제 전환하여 완전한 커버리지를 제공합니다.

확실한 해결책은 아닙니다.가장 불행한 점은 도구의 한계를 해결하기 위해 프로덕션 코드를 수정해야한다는 것입니다. 나는 코드 커버리지 툴이 컴파일러에 의해 생성 된 비동기 상태 머신의 부분을 무시하는 것을 선호한다. 그러나 그 전까지는 완전한 코드 커버리지를 실제로 얻고 자한다면 많은 옵션이 없습니다.

이 해킹에 대한보다 자세한 설명은 여기에서 찾을 수 있습니다 : http://blogs.msdn.com/b/dwayneneed/archive/2014/11/17/code-coverage-with-async-await.aspx

+0

이 링크가 질문에 대답 할 수 있지만 여기에 답변의 핵심 부분을 포함시키고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않게 될 수 있습니다. –

+0

좋아요, 옵션에 대한 요약과 깊이있는 기사에 대한 링크를 추가했습니다. –

관련 문제