Ответ 1
Это было разрешено Нунитом. Теперь вы можете использовать Assert.ThrowsAsync < > ()
https://github.com/nunit/nunit/issues/1190
Пример:
Assert.ThrowsAsync<Exception>(() => YourAsyncMethod());
Я пытаюсь перенести тест на NUnit3 и получаю System.ArgumentException: методы async void не поддерживаются, вместо этого используйте "async Task".
[Test]
public void InvalidUsername()
{
...
var exception = Assert.Throws<HttpResponseException>(async () => await client.LoginAsync("[email protected]", testpassword));
exception.HttpResponseMessage.StatusCode.ShouldEqual(HttpStatusCode.BadRequest); // according to http://tools.ietf.org/html/rfc6749#section-5.2
...
}
Assert.Throws, похоже, принимает TestDelegate, определяемый как:
public delegate void TestDelegate();
следовательно, исключение ArgumentException. Каков наилучший способ для переноса этого кода?
Это было разрешено Нунитом. Теперь вы можете использовать Assert.ThrowsAsync < > ()
https://github.com/nunit/nunit/issues/1190
Пример:
Assert.ThrowsAsync<Exception>(() => YourAsyncMethod());
Я бы рекомендовал следующий код вместо Assert.ThrowsAsync
, так как это более читабельно:
// Option A
[Test]
public void YourAsyncMethod_Throws_YourException_A()
{
// Act
AsyncTestDelegate act = () => YourAsyncMethod();
// Assert
Assert.That(act, Throws.TypeOf<YourException>());
}
// Option B (local function)
[Test]
public void YourAsyncMethod_Throws_YourException_B()
{
// Act
Task Act() => YourAsyncMethod();
// Assert
Assert.That(Act, Throws.TypeOf<YourException>());
}
Чтобы исключение было выбрано, лучше не утверждать в блоке catch, если вы так решите его использовать. Таким образом, вы можете быть уверены, что вы выбрали правильный тип исключения, потому что иначе вы получите нулевую ссылку или неотобравшееся другое исключение.
HttpResponseException expectedException = null;
try
{
await client.LoginAsync("[email protected]", testpassword));
}
catch (HttpResponseException ex)
{
expectedException = ex;
}
Assert.AreEqual(HttpStatusCode.NoContent, expectedException.Response.BadRequest);
В итоге я написал статическую функцию, которая отражает то, что делает NUnit. Был целый разговор в https://github.com/nunit/nunit/issues/464 об этом.
public static async Task<T> Throws<T>(Func<Task> code) where T : Exception
{
var actual = default(T);
try
{
await code();
Assert.Fail($"Expected exception of type: {typeof (T)}");
}
catch (T rex)
{
actual = rex;
}
catch (Exception ex)
{
Assert.Fail($"Expected exception of type: {typeof(T)} but was {ex.GetType()} instead");
}
return actual;
}
Затем из моих тестов я могу использовать его, например
var ex = await CustomAsserts.Throws<HttpResponseException>(async () => await client.DoThings());
Assert.IsTrue(ex.Response.StatusCode == HttpStatusCode.BadRequest);
Вы можете попробовать использовать что-то вроде этого:
try
{
await client.LoginAsync("[email protected]", testpassword);
}
catch (Exception ex)
{
Assert.That(ex, Is.InstanceOf(typeof (HttpResponseException)));
}