2016-08-26 2 views
3

У меня есть приложение, которое загружает огромное количество PDF-файлов из Интернета. Время от времени я получаю исключение HttpRequestException, связанное с сообщением: Ошибка при копировании содержимого в поток.Имитировать HttpRequestException для модульного тестирования

Итак, я пытаюсь выполнить тестирование моего кода, чтобы справиться с этой ситуацией. Мой текущий код скачивания:

var request = await httpClient.GetAsync(url); 

// This is where the exception would be thrown 
await request.Content.ReadAsByteArrayAsync()); 

Теперь я пытаюсь имитировать HttpRequestException, так что я могу модульное тестирование коды выше, но я не знаю, как это сделать. Кто-нибудь может помочь?

Заранее благодарен!

+0

Аннотация вызов httpClient за интерфейсом, которым вы управляете, чтобы вы могли издеваться над ним во время модульного теста, чтобы поднять/смоделировать исключение, которое вы хотите. также с точки зрения именования результат «GetAsync» будет «ответом», а не «запросом». т.е. 'var response = await httpClient.GetAsync (url);' – Nkosi

+0

Я не рассматривал этот вариант использования. Я посмотрю на добавление нового API в mockhttp, чтобы упростить его в будущем. –

+0

Спасибо. Пожалуйста, уточните, когда это возможно. –

ответ

2

Ключевым моментом здесь является создание HttpContent, генерирующий исключение:

public class ExceptionThrowingContent : HttpContent 
{ 
    private readonly Exception exception; 
    public ExceptionThrowingContent(Exception exception) 
    { 
     this.exception = exception; 
    } 

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) 
    { 
     return Task.FromException(exception); 
    } 

    protected override bool TryComputeLength(out long length) 
    { 
     length = 0L; 
     return false; 
    } 
} 

После того, как вы есть, что вы можете использовать что-то вроде моей mockhttp издеваться запрос:

var handler = new MockHttpMessageHandler(); 
handler.When("http://tempuri.org/url") 
    .Respond(new ExceptionThrowingContent(ex)); 

var mockClient = new HttpClient(handler); 

// pass mockHandler to your component 

Теперь, если ваш компонент переходит в HttpCompletionOption.ResponseHeadersRead, когда он делает запрос, исключение будет выбрано в await Content.ReadAsByteArrayAsync(). Если нет, HttpClient попытается буферизовать ответ, поэтому исключение будет выбрано в await HttpClient.GetAsync().

Если ответ является буферизации, это реально «невозможно» за исключением быть брошенным в ReadAsByteArrayAsync так что нет никакого смысла в попытке имитировать его. («невозможно» за пределами OutOfMemoryException)

+0

Выглядит очень здорово !!! Как вы думаете, возможно ли исключение, вызванное ожиданием ответа.Content.ReadAsByteArrayAsync() Я не был достаточно ясен :(Извините. На данный момент исключение бросается в ожидании. MockClient.GetAsync («http://tempuri.org/url») –

+0

Обновлено, чтобы вернуть исключающее исключение Tas k вместо этого. Дайте это. –

+0

Не работает :(Если бы вы могли сэкономить время, чтобы проверить это, я бы очень признателен –

1

С MockHttp это Простая настройка HttpClient тесты в беглой манере вы можете вернуть настроенную HttpContent, что бросает HttpRequestException как в этом примере.

[TestMethod] 
[ExpectedException(typeof(HttpRequestException))] 
public async Task Test() 
{ 
    var content = new ContentWithException(); 
    var mockHttp = new MockHttpMessageHandler(); 
    mockHttp.Expect("http://localhost/mypdfDownload").Respond(content); 

    var client = new HttpClient(mockHttp); 
    var response = await client.GetAsync("http://localhost/mypdfDownload"); 

    await response.Content.ReadAsByteArrayAsync(); 
} 

private class ContentWithException : HttpContent 
{ 
    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) 
    { 
     throw new HttpRequestException(); 
    } 

    protected override bool TryComputeLength(out long length) 
    { 
     length = 0; 
     return false; 
    } 
} 
+0

Выглядит очень здорово !!! Считаете ли вы возможным, чтобы исключение было отправлено в ожидании ответа. Контент.ReadAsByteArrayAsync(); ? Я не был достаточно ясен :(Извините. На данный момент исключение вызывается в ожидании client.GetAsync («http: // localhost/mypdfDownload») –

+0

@FernandoSilva: Я просмотрел его, и я не придумал с решением все же. В обоих случаях (как в ответе от @Richard Szalay) HttpClient начинается с «GetAsync» для доступа к содержимому (асинхронная буферизация). Таким образом, исключение вызывается там, а не позже в «ReadAsByteArrayAsync()», Я подумал о другом решении. –

+0

Спасибо, пожалуйста, обновите, когда у вас есть шанс –

Смежные вопросы