1

Я новичок в мире async/await, и я пытаюсь понять преимущества написания асинхронных модульных тестов для асинхронных методов. То есть, должен ли единичный тест для метода асинхронного вызова асинхронным способом асинхронного метода? Если он синхронно вызывает метод асинхронного использования Task.Run(), что потеряно? В последнем случае покрытие кода не влияет, насколько я вижу.Неправильно ли вызывать синхронно вызов асинхронных методов в модульных тестах?

Причина, по которой я прошу об этом, заключается в том, что наше насмешливое программное обеспечение (мы используем TypeMock) не может поддерживать async/wait. (They say there is a legitimate reason за это отсутствие поддержки, и я не согласен с ними.) При вызове методов асинхронного синхронного тестирования в модульных тестах мы можем решить эту проблему. Тем не менее, я хотел бы узнать, разрезаем ли мы любой угол, делая это.

Например, предположим, что у меня есть следующий метод асинхронного:

public async Task<string> GetContentAsync(string source) 
{ 
    string result = ""; 
    // perform magical async IO bound work here to populate result 
    return result; 
} 

Следующие является идеальным тестовым модулем, который не работает:

[TestMethod()] 
public async Task GetContentAsyncTest() 
{ 
    string expected = "thisworks"; 
    var worker = new Worker(); 
    // ...mocking code here that doesn't work! 
    string actual = await worker.GetContentAsync(); 
    Assert.AreEqual(expected, actual); 
} 

Но это работает, и это делает предоставить необходимый нам код. Это нормально?

[TestMethod()] 
public void GetContentAsyncTest() 
{ 
    string expected = "thisworks"; 
    var worker = new Worker(); 
    // mocking code here that works! 
    string actual = Task.Run(() => worker.GetContentAsync()).Result; 
    Assert.AreEqual(expected, actual); 
} 
+0

Я не являюсь поклонником этого вопроса; название немного шире. В большинстве случаев вы не проверяете, не занималось ли что-то X длинным или Y длинным, вы просто говорите: «Если это сделано, убедитесь, что это произошло» или «Убедитесь, что это произошло, если оно не удалось». Является ли это Async или нет, не вступает в игру в подавляющем большинстве случаев. –

+0

Асинхронная обработка в основном для освобождения пула потоков или рабочих процессов IIS – saj

+0

@George Stocker Я знаю, но тот факт, что я вижу примеры тестов асинхронного модуля, заставляет меня думать, что есть причина, по которой люди пишут их. Что вы предлагаете для названия тогда? Разве вы не можете дать мне шанс улучшить его до того, как он начнется? Чуть-триггер счастлив? – Zoomzoom

ответ

3

должен выполнить единичный тест для вызова метода асинхронного вызова асинхронным способом?

Нет, но это наиболее естественно сделать.

Если он синхронно вызывает метод асинхронного использования Task.Run(), что потеряно?

Ничего особенного. Это немного менее результативно, но в той степени, что вы, вероятно, никогда не заметите.

Возможно, вы захотите использовать GetAwaiter().GetResult() вместо Result, чтобы избежать оберток AggregateException в тестах отказов. И вы также можете просто вызвать метод напрямую; нет необходимости обертывать его в Task.Run.

Говорят, что для этого недостатка поддержки существует законная причина, и я не согласен с ними.

О, я определенно не согласен с ними. :)

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


Единственными более серьезной проблемы не поддерживает async модульных тесты, если код тестируемого предполагается его контекст будет обрабатывать синхронизацию. Это обычное явление, например, в умеренно сложных моделях.

В этом случае вам необходимо установить контекст, в котором должен выполняться код async (например,, мой AsyncContext type), если вы не используете единую тестовую структуру, которая автоматически предоставляет один (на момент написания этой статьи только xUnit делает AFAIK).

+0

К вашему второму пункту, касающемуся потери производительности - даже если это было важно, все равно это не было бы проблемой для модульных тестов. – Zoomzoom

+0

@Zoomzoom: Я не согласен. В определенной степени важно [производительность модульных тестов] (http://xunitpatterns.com/Slow%20Tests.html). –

+0

Стивен - я вижу. Трудно спорить с этим! Тем не менее, для моей ситуации производительность теста была не так важна, как покрытие кода. – Zoomzoom

2

Если вы используете xUnit вместо MSTest, ваше идеальное решение (асинхронный тест) будет работать.

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