Как установить ожидания для звонков, которые будут сделаны в другой теме в Rhino Mocks - PullRequest
1 голос
/ 08 октября 2008

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

 MockRepository mocks = new MockRepository();
ICacheManager manager = mocks.CreateMock<ICacheManager>();

Expect.On(manager).Call(manager.CacheSize).Return(100);
mocks.ReplayAll();

CacheJanitor janitor = new CacheJanitor(manager);

// get janitor to do its stuff
// ...

mocks.VerifyAll();

Проблема в том, что при проверке мы получаем два исключения: одно в тестовом потоке, сообщающее, что вызов CacheSize ожидался, но не произошел, а другое в фоновом потоке (в пределах CacheJanitor), в котором говорится, что звонок на CacheSize произошел, но не ожидался.

Очевидно, что ожидания имеют сходство с потоком, в котором они создаются. Кто-нибудь знает способ проинструктировать Rhino Mocks ожидать вызова в другом потоке (который даже не существует в то время, когда ожидания определены)?

РЕДАКТИРОВАТЬ:

Забыл упомянуть об ограничении, что мы все еще на VS 2005 на ближайшее будущее. Rhino Mocks версия 3.4 - я попробую с 3.5, но список улучшений, похоже, не указывает на какие-либо исправления в этой области.

На данный момент я, вероятно, создам свой собственный смоделированный объект для этой серии тестов и запишу результаты в нем, но определенно буду признателен за любые решения, которые позволят мне достичь этого с помощью Rhino Mocks.

1 Ответ

1 голос
/ 08 октября 2008

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

Какую версию Rhino вы используете? Вы используете его до 3.5; возможно это не будет проблемой с версией 3.5?

Другая альтернатива - избегать проверки ожиданий на макетах. (извините, я не знаком с синтаксисом Rhino, но это возможно). Используйте обратный вызов, чтобы установить локальную переменную в тестовой функции и проверить ее.

В MoQ я бы сделал это так:

// Arrange
var called = false;
var mock = new Mock<SomeObject>();            

mock.Expect(x => SomeFunction()).Callback(() => called = true);            

var target = new MultithreadedTarget(mock.Object);            

// Act
target.DoSomethingThatCallsSomeFunctionOnAnotherThreadLol();            

// this part is a bit ugly
// spinlock for a bit to give the other thread a chance
var timeout = 0;
while(!called && timeout++ < 1000)
  Thread.Sleep(1);

// Assert
Assert.IsTrue(called);
...