Убедитесь, что вызов метода происходит в отдельном пуле / потоке потоков с использованием Moq - PullRequest
2 голосов
/ 27 марта 2019

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

Я применил шаблон наблюдателя, поэтому я издеваюсь IObserver<T>:

var mock = new Mock<IObserver<T>>();
mock.Setup(s => s.OnCompleted());

Здесь OnCompleted() выглядит примерно так

public void OnCompleted()
{
}

Теперь в тесте, используя mock, я делаю так:

// observable is the SUT.
var unsubscriber = observable.Subscribe(mock.Object);
// Cause OnCompleted() to be called: I verified that there's one observer in the observers list in observable and that my break point is correctly hit.

mock.Verify(v => v.OnCompleted(), Times.AtLeastOnce);
unsubscriber.Dispose(); 

Я получаю следующую ошибку:

Message: Moq.MockException : 
Expected invocation on the mock at least once, but was never performed: v => v.OnCompleted()

Configured setups: 
IObserver<T> s => s.OnCompleted()
No invocations performed.

РЕДАКТИРОВАТЬ:Код SUT

SUT - это класс, инициализированный с использованием фабричного метода.Я суммирую соответствующие части здесь:

Есть метод инициализатора:

public void InitializeMyClass()
{
   for(var i = 0; i < threads.Count; i++)
   {
       Task.Factory.StartNew(() => Proc())
   }

   this.timer = new Timer(CheckStatus, null, 0, 1000);
}

CheckStatus метод проверяет, достигает ли рабочая нагрузка в потоках, запущенных в Initializer, определенный статус и поднимаетсобытие, указывающее на завершение:

private void CheckStatus(object status)
{
   // Inspect all background threads.
   // This is simply done by observing a set of values in a concurrent dict<int, bool>.:

   if (!this.concurrentDict.Values.Any(a => a))
   {
       this.NotifyObservers();
       this.timer.Change(Timeout.Infinite, Timeout.Infinite);
   }
}

NotifyObservers() вызывает метод OnCompleted():

private void NotifyObservers()
{
    foreach(o in observers)
    {
        o.OnCompleted();
    }
}

1 Ответ

3 голосов
/ 28 марта 2019

Это может быть проблема с многопоточностью или таймер может не быть запущен к моменту проверки.Это означает, что фиктивные участники еще не были вызваны, когда был вызван Verify.

Возможно, вам придется немного подождать, прежде чем проверять вызов метода.

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

//Arrange

//...

//Act
// observable is the SUT.
var unsubscriber = observable.Subscribe(mock.Object);
// Cause OnCompleted() to be called: I verified that there's one observer in the observers list in observable and that my break point is correctly hit.

await Task.Delay(TimeSpan.FromSeconds(1.5)); //Or some known duration

//Assert    
mock.Verify(v => v.OnCompleted(), Times.AtLeastOnce);
unsubscriber.Dispose(); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...