2015-10-02 3 views
1

У меня есть следующий метод:Verify методы вызываются в порядке

public async Task DeleteAmendment(int amendmentHeaderId, int userId) 
{ 
    // Delete the corresponding version records. 
    await _amendmentVersionService.DeleteForAmendmentAsync(amendmentHeaderId); 

    // Delete the corresponding lifecycle records. 
    await _amendmentLifecycleService.DeleteForAmendmentAsync(amendmentHeaderId); 

    // Delete the amendment header record itself. 
    await _amendmentHeaderService.DeleteAsync(amendmentHeaderId, userId); 
} 

Я пытаюсь проверить, что методы вызываются в порядке.

Я попытался установить обратные вызовы (смотри ниже)

AmendmentVersionService.Setup(x => x.DeleteForAmendmentAsync(It.IsAny<int>())) 
    .Callback(() => ServiceCallbackList.Add("AmendmentVersionService")); 

AmendmentLifecycleService.Setup(x => x.DeleteForAmendmentAsync(It.IsAny<int>())) 
    .Callback(() => ServiceCallbackList.Add("AmendmentLifecycleService")); 

AmendmentHeaderService.Setup(x => x.DeleteAsync(It.IsAny<int>(), It.IsAny<int>())) 
    .Callback(() => ServiceCallbackList.Add("AmendmentHeaderService")); 

Но список содержит только строку "AmendmentVersionService"

Любые идеи?

+1

Почему бы им не называть их по порядку? если вы используете ожидание в каждом из них, выполнение будет ждать завершения каждого из них до вызова следующего. – JoaoFSA

+0

Можете ли вы показать нам остальную часть теста, где вы называете DeleteAmendment? – JonE

+0

http://hastebin.com/mawisanani.avrasm – swade1987

ответ

0

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

для первого вызова:

  • настройки вызова 2 бросить исключение пользовательского типа TestException.
  • утверждает только вызов 1 было выполнено
  • Ожидать TestException быть выброшен

для второго вызова:

  • установки вызов-бросить исключение пользовательского типа TestException.
  • утверждают вызов 1 и 2 были выполнены
  • Ожидать TestException быть выброшен

для третьего звонка:

  • Setup все вызовы нормально работать.
  • утверждает вызов 1, 2 и 3 были выполнены
0

Вы можете использовать продолжения (ниже), но на самом деле, если вам нужно garuntee, что эти вещи происходят в порядке, то они не должны быть операциями асинхронными. Обычно вы хотите, чтобы операции async могли работать одновременно;

public async Task DeleteAmendment(int amendmentHeaderId, int userId) 
{ 
    Task.Run(() => 
    { 
     // Delete the corresponding version records. 
     await _amendmentVersionService.DeleteForAmendmentAsync(amendmentHeaderId); 
    }).ContinueWith(_ => 
    { 
     // Delete the corresponding lifecycle records. 
     await _amendmentLifecycleService.DeleteForAmendmentAsync(amendmentHeaderId); 
    }).ContinueWith(_ => 
    { 
     // Delete the amendment header record itself. 
     await _amendmentHeaderService.DeleteAsync(amendmentHeaderId, userId); 
    }); 
} 
+0

Я думаю, что это на самом деле ему не помогает: он хочет убедиться, что продолжения выполняются в правильном порядке, с модульными тестами, а не в реализации. –

+0

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

+0

_ou не верно работает асинхронная операция, если порядок имеет значение. Я категорически не согласен. асинхронный не равен параллели. ** но ** это не главное. Он хочет провести тесты, чтобы убедиться, что никто не испортил код и не перевернул порядок, в котором выполняются вызовы, независимо от того, было ли это сделано с ожиданием или ConitnueWith. –

0

Ваша проблема в том, что вы никогда не будете иметь возможность знать, если метод был выполнен в результате предыдущего отделочного (ожидаемый), или если вы были достаточно удачливы, чтобы не страдать от состояния гонки (вызов, сделанный без Await, или нет ContinueWith)

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

Мы сделали это в Testeroids, испытательном каркасе, другом и мной.

Таким образом, ваш пользовательский TaskScheduler может выполнять задачи последовательно, в одном потоке (чтобы действительно выделить проблемы с временной шкалой, которые у вас могли бы быть) и записывать, какие задачи были запланированы и в каком возрасте.

Это потребует больших усилий с вашей стороны, если вы хотите быть настолько основательным, но по крайней мере вы получите эту идею.

Чтобы заменить Defaukt TaskScheduler, вы можете получить вдохновение от работы, которую мы сделали на Testeroids.

https://github.com/Testeroids/Testeroids/blob/c5f3f02e8078db649f804d94c37cdab3df89fed4/solution/src/app/Testeroids/TplTestPlatformHelper.cs

0

Благодаря Стивен Брикнера ...

я сделал все мои звонки, синхронные, который сделал обратные вызовы в работе MOq как сон.

Спасибо за вашу помощь!

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