Носорог, пустоты и свойства

2

Просто начинайте с Rhino Mocks и им, имея очень простую проблему, как я издеваюсь над классом с void, который устанавливает свойство?

class SomeClass : ISomeClass
{
    private bool _someArg;

    public bool SomeProp { get; set; }

    public SomeClass(bool someArg)
    {
        _someArg = someArg; 
    }

    public void SomeMethod()
    {
        //do some file,wcf, db operation here with _someArg
        SomeProp = true/false;
    }
}

Очевидно, это очень надуманный пример, спасибо.

Теги:
mocking
tdd
rhino-mocks

4 ответа

6
Лучший ответ

В вашем примере вам не понадобятся RhinoMocks, потому что вы, по-видимому, проверяете функциональность тестируемого класса. Вместо этого выполните простое тестирование:

[Test]
public void SomeTest()
{
    var sc = new SomeClass();
        // Instantiate SomeClass as sc object
    sc.SomeMethod();
        // Call SomeMethod in the sc object.

    Assert.That(sc.SomeProp, Is.True );
        // Assert that the property is true... 
        // or change to Is.False if that what you're after...
}

Гораздо интереснее тестировать mocks, когда у вас есть класс, который имеет зависимости от других классов. В вашем примере вы упомянули:

//Делаем некоторые операции с файлом, wcf, db здесь с _someArg

т.е. вы ожидаете, что какой-либо другой класс установит свойство SomeClass, что имеет смысл сделать mocktest. Пример:

public class MyClass {

    ISomeClass _sc;

    public MyClass(ISomeClass sc) {
        _sc = sc;
    }

    public MyMethod() {
        sc.SomeProp = true;
    }

}

Требуемый тест будет выглядеть примерно так:

[Test]
public void MyMethod_ShouldSetSomeClassPropToTrue()
{
    MockRepository mocks = new MockRepository();
    ISomeClass someClass = mocks.StrictMock<ISomeClass>();

    MyClass classUnderTest = new MyClass(someClass);

    someClass.SomeProp = true;
    LastCall.IgnoreArguments();
        // Expect the property be set with true.

    mocks.ReplayAll();

    classUndertest.MyMethod();
        // Run the method under test.

    mocks.VerifyAll();
}
  • 0
    В вашем последнем примере Lastcall.IgnoreArguments (); будет ложным, потому что вы также можете пройти тест, передав someClass.SomeProp = false;
3

В зависимости от того, насколько вы верны в своем макетном объекте. Легкий способ сделать это - не беспокоиться об этом и выписывать некоторые немые ожидающие утверждения.

[Test]
public void SomeTest()
{
   MockRepository mocks = new MockRepository();
   ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>();
   using(mocks.Record())
   {
      using(mocks.Ordered())
      {
         Expect.Call(MockSomeClass.SomeProp).Return(false);
         Expect.Call(delegate{MockSomeClass.SomeMethod();});
         Expect.Call(MockSomeClass.SomeProp).Return(true);
      }
   }
}

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

delegate bool propDelegate();
delegate void methodDelegate();
private bool m_MockPropValue = false;

[Test]
public void SomeTest()
{
   MockRepository mocks = new MockRepository();
   ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>();
   using(mocks.Record())
   {
      SetupResult.For(MockSomeClass.SomeProp).Do(new propDelegate(delegate
      {
         return this.m_MockPropValue;
      }));
      Expect.Call(delegate{MockSomeClass.SomeMethod();}).Do(new methodDelegate(delegate
      {
         this.m_MockPropValue = true;
      }));
   }
}
  • 0
    И как я могу утверждать, что SomeMethod был вызван?
  • 0
    Используя Expect.Call (s => s.SomeMethod ())
Показать ещё 1 комментарий
0

Неясно, из какого объекта вы пытаетесь проверить, что объект, который вы пытаетесь проверить, - если вы просто хотите проверить, что SomeClass.SomeMethod() устанавливает свойство, вам не нужно насмехаться, так как вы можете просто сделать простой государственный тест:

[TestMethod]
public void SomeMethodTest()
{
    SomeClass s = new SomeClass();
    s.SomeMethod();

    Assert.AreEqual(expectedValue, s.SomeProp);
}

В качестве альтернативы, если SomeClass является зависимостью для какого-либо другого класса, и вы хотите протестировать взаимодействие между этим классом и SomeClass, тогда вы настроите ожидание на вызов метода в разделе "Запись" теста, используя RhinoMock, например:

[TestMethod]
    public void CheckInteractionWithSomeClass()
    {
        MockRepository mocks = new MockRepository();
        ISomeClass someClass = mocks.StrictMock<ISomeClass>();

        using (mocks.Record())
        {
            //record expection that someClass.SomeMethod will be called...
            someClass.SomeMethod();
        }

        using (mocks.Playback())
        {
            //setup class under test - ISomeClass is injected through the constructor here...
            ClassUnderTest o = new ClassUnderTest(someClass);

            o.MethodOnClassUnderTestThatShouldCallSomeClass.SomeMethod();

            //any other assertions...
        }
    }
0

Когда вы готовите что-либо с помощью SetupResult.For или Expect.Call, вам нужно убедиться, что они виртуальны, иначе RhinoMocks не сможет выполнить свою собственную реализацию.

В противном случае это просто вопрос определения результатов и ожидаемых вызовов как Скотт Педерсен показал

Ещё вопросы

Сообщество Overcoder
Наверх
Меню