비동기/대기 패턴에 익숙하지만 비정상적인 동작이 발생합니다. 내가 왜 그런 일이 일어나고 있는지 완벽하게 타당한 이유가 있으며, 그 행동을 이해하고 싶습니다.비동기 전달시 예기치 않은 동작이 발생했습니다.
여기 배경은 내가 Windows Store 앱을 개발하고 있으며, 나는 신중하고 양심적 인 개발자이기 때문에 모든 것을 테스트하고있다. 꽤 빨리 WS35에 ExpectedExceptionAttribute
이 존재하지 않는다는 것을 발견했습니다. 이상하지, 그렇지? 글쎄, 아무 문제 없어! 확장 메서드를 사용하여 동작을 더 많이 또는 덜 복제 할 수 있습니다! 그래서 나는 이것을 썼다 :
public static class TestHelpers
{
// There's no ExpectedExceptionAttribute for Windows Store apps! Why must Microsoft make my life so hard?!
public static void AssertThrowsExpectedException<T>(this Action a) where T : Exception
{
try
{
a();
}
catch (T)
{
return;
}
Assert.Fail("The expected exception was not thrown");
}
}
그리고 아름답게 작동한다.
그래서 내가 확신하고 싶은 비동기 메서드를 누르기 전까지 단위 테스트를 행복하게 계속 작성하여 특정 상황에서 예외가 발생했습니다. "문제 없습니다."나는 비공식 람다를 전달할 수 있다고 생각했습니다.
[TestMethod]
public async Task Network_Interface_Being_Unavailable_Throws_Exception()
{
var webManager = new FakeWebManager
{
IsNetworkAvailable = false
};
var am = new AuthenticationManager(webManager);
Action authenticate = async() => await am.Authenticate("foo", "bar");
authenticate.AssertThrowsExpectedException<LoginFailedException>();
}
이 놀랍게도, 런타임 오류가 발생합니다 :
그래서 나는이 시험 방법을 썼다. 실제로는 이 충돌합니다. 테스트 러너! 나는 나의AssertThrowsExpectedException
방법의 과부하를 만든 :
public static async Task AssertThrowsExpectedException<TException>(this Func<Task> a) where TException : Exception
{
try
{
await a();
}
catch (TException)
{
return;
}
Assert.Fail("The expected exception was not thrown");
}
나는 내 테스트를 쥐게 : 모든가는 이유
[TestMethod]
public async Task Network_Interface_Being_Unavailable_Throws_Exception()
{
var webManager = new FakeWebManager
{
IsNetworkAvailable = false
};
var am = new AuthenticationManager(webManager);
Func<Task> authenticate = async() => await am.Authenticate("foo", "bar");
await authenticate.AssertThrowsExpectedException<LoginFailedException>();
}
내 솔루션 괜찮아, 난 그냥 정확히 궁금하네요 비동기 Action
을 호출하려고하면 배 모양입니다. 런타임과 관련하여 이 아니기 때문에이 Action
이 아니므로, 나는 그 안에 람다를 넣었습니다. 나는 람다가 행복하게 Action
또는 Func<Task>
에 할당된다는 것을 알고 있습니다.
Windows 테스트에서 'Assert'를 사용하십시오.(as VS2012 Update 2 (http://support.microsoft.com/kb/2797912))는'async' lambdas를 지원합니다. 'Func'은 반환 값이없는 * 비동기 * 메소드 인 반면,'Action'은 반환 값이없는 * synchronous * 메소드입니다. –
오, 나는 Assert.ThrowsException을 알지 못했다. 나는 그것을 사용하기 위해 나의 테스트를 바꿀 것이다. –