xUnit не всегда ловит асинхронное исключение - PullRequest
0 голосов
/ 03 февраля 2019

Я создал тест xUnit, который дважды вызывает метод, чтобы гарантировать, что второй вызов выдает исключение, сообщающее, что экземпляр класса занят.Довольно просто.

[Fact]
public async Task RunTwice() {
    var P = Create();
    Task T1 = Task.Run(() => P.Run("test", null));
    Task T2 = Task.Run(() => P.Run("test", null));
    await Assert.ThrowsAsync<InvalidOperationException>(() => Task.WhenAll(new Task[] { T1, T2 }));
}

Проблема в том, что этот тест будет случайным образом либо успешным, либо неудачным!

Метод Run запускается так:

public IProcess WorkProcess;
private readonly object lockToken = new object();

public virtual CompletionStatus Run(string fileName, string arguments) {
    IProcess P;
    lock (lockToken) {
        if (WorkProcess != null)
            throw new InvalidOperationException();
        P = factory.Create();
        WorkProcess = P;
    }
...

Это покупка?xUnit или я что-то не так делаю?Я знаю, что поддержка асинхронности была добавлена ​​в xUnit 1.9.Я использую v2.4.1.

Когда я смотрю на отладочную информацию, когда тест не проходит, исключение все еще выдается.

1 Ответ

0 голосов
/ 05 февраля 2019

Похоже, вы делаете что-то не так.Task.Run просто планирует работу в пул потоков.Возможно, они попытаются позвонить Run одновременно, возможно, одно произойдет за другим.То, что вы пытаетесь сделать, присуще состоянию гонки.

Чтобы решить эту проблему, вам потребуется какой-нибудь способ для модульного теста контролировать код внутри Run и «ставить его на паузу».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...