Похоже, вы не работали с более поздними фреймворками фиктивных объектов.
В более старых "фиктивных объектах" вы должны делать утверждения вручную относительно состояния фиктивного объекта.Например, вы запускаете тестируемый код, который добавляет элементы в список на вашем фиктивном объекте.В конце теста вы убедитесь, что список этого фиктивного объекта заполнен правильно.Это проверяет состояние макета.
Этот старый стиль похож на менее изощренную версию заглушки Rhino.
С более новыми платформами фиктивных объектов вы прекращаете проверять состояние фиктивных объектов иначать проверять поведение.Вы делаете утверждения о том, как тестируемый код вызывает ваши фиктивные объекты, а не о том, как задаются свойства / элементы.
Вы все равно будете делать классические утверждения для тестируемого кода.Но вы не будете делать классические утверждения на ваших издевательствах.Вместо этого вы настроите ожидания и подтвердите их с помощью утверждений Rhino.
Несколько советов по исправлению этого кода:
- Здесь используются две части API Rhino Mocks.Отбросьте часть записи / воспроизведения, так как она более запутанная, и придерживайтесь синтаксиса AAA (Arrange, Act, Assert).См. примечания к выпуску с момента добавления AAA
- Остановите тестирование фиктивных объектов напрямую
- Проверьте код, который использует фиктивный объект, и добавьте ожидания длякакой этот код вызовет на макете
- Вызовите тестируемый код перед вызовом на
VerifyAllExepectations
, передавая ему при необходимости макеты - Убедитесь, что методы исвойства, которые вы хотите смоделировать, помечены
virtual
или abstract
, или что ваш смоделирован на основе interface
- Разделите ваши тестовые случаи на тесты, которые проверяют вызовы имитаций, и тесты, которые проверяют состояние /возвращаемые значения верны в тестируемом коде
- Не устанавливайте состояние для макетов вообще, поскольку вы устанавливаете его напрямую, и это просто тестирует ваш тестовый пример
Вот некоторые исправленныепример кода:
public class ObjectThatUsesPerson
{
public ObjectThatUsesPerson(Person person)
{
this.person = person;
}
public string SomeMethod()
{
return person.Title;
}
private Person person;
}
[TestMethod]
public void TestingPropertyGotCalled()
{
// Arrange
var mockPerson = MockRepository.GenerateMock<Person>();
mockPerson.Expect(x => x.Title).Return("Monica");
var someObject = new ObjectThatUsesPerson(mockPerson);
// Act
someObject.SomeMethod(); // This internally calls Person.Title
// Assert
repository.VerifyAllExpectations();
// or: mockPerson.AssertWasCalled(x => x.Title);
}
[TestMethod]
public void TestingMethodResult()
{
// Arrange
var stubPerson = MockRepository.GenerateStub<Person>();
stubPerson.Stub(x => x.Title).Return("Monica");
var someObject = new ObjectThatUsesPerson(stubPerson);
// Act
string result = someObject.SomeMethod();
// Assert
Assert.AreEqual("Monica", result, "Expected SomeMethod to return correct value");
}
Чтобы проверить, что это работает правильно, попробуйте выполнить следующие действия (измените код после каждого):
- Запустите его один раз и убедитесь, что он прошел
- Удалить строку
Expect
, ги убедитесь, что он все еще проходит (это не строгая насмешка) - Добавьте дополнительную строку
Expect
, возвращая другое значение.Запустите его и убедитесь, что он не работает - Добавьте дополнительный
SomeMethod
вызов.Запустите его и убедитесь, что оно прошло (не строгая проверка) - Удалите код внутри
SomeMethod
.Запустите его и убедитесь, что он не работает