Добро пожаловать в переполнение стека!
Ваше тело ответа пусто, потому что вы пишете в NullStream
(не путать со значением null
).
"Поток без резервного хранилища. Используйте Null, чтобы перенаправить вывод в поток, который не будет потреблять ресурсы операционной системы. Когда методы Stream, обеспечивающие запись, вызываются на Null, вызов просто возвращается, и данные отсутствуют. записано. Null также реализует метод Read, который возвращает ноль без чтения данных. " - Документы
Значение по умолчанию Body
, свойство HttpResponse
точно
NullStream
. В реальном сценарии, когда приходит HTTP-запрос, NullStream
заменяется на HttpResponseStream
. Вы не сможете использовать его самостоятельно, поскольку его уровень доступности установлен на internal
.
Решение
Поскольку модульное тестирование только моделирует реальный сценарий, вы можете просто заменить NullStream
на любой тип потока, который вы хотите, например, MemoryStream
:
var exceptionHandler = new ExceptionHandler((innerHttpContext) =>
{
throw new Exception("Test exception");
}, new NullLogger<ExceptionHandler>());
var context = new DefaultHttpContext();
context.Response.Body = new MemoryStream(); // <== Replace the NullStream
await exceptionHandler.Invoke(context);
context.Response.Body.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(context.Response.Body);
var text = reader.ReadToEnd();
Не забудьте добавить некоторые утверждения в конце ваших модульных тестов. В конце концов, вы хотите выполнить некоторые проверки, верно?
Assert.IsFalse(string.IsNullOrEmpty(text));
РЕДАКТИРОВАТЬ # 1
Как отметил @nkosi, если у вас нет веских причин, вы всегда должны вызывать асинхронные методы с ключевым словом await
:
await exceptionHandler.Invoke(context);
и пометьте определение метода с помощью async
и верните ему Task
:
public async Task HandleException()
Таким образом, вы избегаете тупиков .
Что-то, на что также стоит обратить внимание (но не на необходимость), это соглашение об именах для тестирования классов. Очевидно, вы можете называть его так, как вам нравится, но имейте в виду, что когда у вашего класса тестирования будет то же имя, что и у класса, который вы хотите протестировать, вы получите ненужную двусмысленность имен. Конечно, вы можете написать полное имя с пространством имен (как вы сделали), но с моей ленивой натурой, это слишком много, поэтому я использую другое имя для тестирования класса, например ExceptionHandlerTests
.