Почему Rhino Mocks создает исключение при использовании его с потоками? - PullRequest
2 голосов
/ 20 сентября 2010

у нас возникла проблема при использовании Rhino Mocks и Threads. Я пытался выделить проблему, но теперь я застрял в этом:

[TestClass]
public class FoolTests
{
   [TestMethod]
   public void TestMethod_Scenario_Result()
   {
       for (int i = 0; i < 5; i++)
       {
           var fool = MockRepository.GenerateStub<IFool>();
           fool.Stub(x => x.AmIFool).Return(false);
           new Fool(fool);
       }
   }
}

public class Fool
{
   private readonly IFool _fool;
   private readonly Thread _thread;

   public Fool(IFool fool)
   {
       _fool = fool;
       _thread = new Thread(Foolish);
       _thread.Start();
   }

   private void Foolish()
   {
       while (true)
       {
           var foo = _fool.Foolness;
       }
   }
}

public interface IFool
{
   bool AmIFool { get; }
   bool Foolness { get; set; }
}

Почти все время, когда я запускаю этот тест, я получаю «Метод теста FoolTests.TestMethod_Scenario_Result выбросил исключение: System.InvalidOperationException: это действие недопустимо, когда фиктивный объект находится в состоянии воспроизведения». on line "fool.Stub (x => x.AmIFool) .Return (false);".

Понятия не имею, что здесь должно быть не так. У кого-нибудь есть идея или мне нужно копаться в коде Rhino Mocks?

1 Ответ

3 голосов
/ 20 сентября 2010

Не уверен, что это полный ответ, но на этой странице есть интересное примечание о многопоточности:

http://www.ayende.com/projects/rhino-mocks/api/files/MockRepository-cs.html

MockRepository может выполнять проверку в нескольких потоках, но запись в несколько потоков не рекомендуется.

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

[TestMethod]
public void TestMethod_Scenario_Result()
{
    var stubs = new IFool[5];
    for (int i = 0; i < stubs.Length; ++i)
    {
        var fool = MockRepository.GenerateStub<IFool>();
        fool.Stub(x => x.AmIFool).Return(false);
        stubs[i] = fool;
    }

    foreach (var stub in stubs)
        new Fool(stub);
}

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

...