Используя Rhino Mocks, как я могу установить свойство параметра для метода Mocked - PullRequest
3 голосов
/ 11 марта 2009

При использовании нового стиля тестирования Rhino Mocks 3.5 Arrange / Act / Assert (AAA) у меня возникли проблемы при написании теста.

У меня есть метод, который вызывает метод в классе репозитория. ActivateFoo, где мой объект Foo имеет свойство IsActive. Результат объекта ActivateFoo должен изменить свойство.

Вот пример кода:

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
  // arrange
  var repo = MockRepository.GenerateMock<IRepository>();
  var foo = new Foo() { ID = 1, IsActive = false };
  var target = new Presenter(repo);
  repo.Expect(x => x.ActivateFoo(foo)).Return(true);

  // act
  target.Activate(foo);

  // assert
  Assert.IsTrue(foo.IsActive);
  repo.VerifyAllExpectations();  
}

Я предполагаю, что ключевой фрагмент кода будет между "ActivateFoo (foo))". и «Возврат (истина);».

Один момент, чтобы прояснить, как работает метод цепочки вещей за кулисами. Если на строке, которую я ожидаю, написан код, имеет ли значение, если это после Return () или до? (если, конечно, решение не использует перегрузку MethodOptions Expect или что-то еще).

Заранее спасибо за любую помощь.

Ответы [ 4 ]

1 голос
/ 11 марта 2009

Благодаря AB Kolan это код, который я использовал и работает.

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
    // arrange
    var repo = MockRepository.GenerateMock<IRepository>();
    var foo = new Foo() { ID = 1, IsActive = false };
    var target = new Presenter(repo);
    repo.Expect(x => x.ActivateFoo(foo)).
        Do(new Func<Foo, bool>(
            delegate(Foo f) { f.IsActive = true; return true; }
        ));

    // act
    target.Activate(foo);

    // assert
    Assert.IsTrue(foo.IsActive);
    repo.VerifyAllExpectations();
}

Мне не нравится иметь дополнительные методы функций для одноразового использования теста, предпочитая встроенный делегат, если это возможно.

Чтобы решить вопрос, это то, что я должен делать или не так, как дизайн. Поскольку имена там, это не точный код и внутри метода target.Activate (). Код в Activate () выполняет некоторую проверку и, при необходимости, выполняет хранилище ActivateFoo (), а затем проверяет результат этой операции и выполняет другие действия.

Так что, возможно, позже мне придется реорганизовать это и разделить шаги, но сейчас я заставил его работать.

Спасибо

0 голосов
/ 11 марта 2009

Судя по всему, ActivateFoo должен быть пустым методом. И так как вы издеваетесь над этим, вам не следует проверять, что это что-то меняет на вашем объекте.

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

0 голосов
/ 11 марта 2009

Вы можете попробовать что-то подобное, используя обработчик Do. Я искренне считаю, что ActivateFoo должен иметь тип возврата void. Но вот код для ActivateFoo с типом возврата bool.

    [TestMethod]
    public void Should_update_foo_to_active_inside_of_repository()
    {
        // arrange
        var repo = MockRepository.GenerateMock<IRepository>();
        var foo = new Foo() { ID = 1, IsActive = false };
        var target = new Presenter(repo);
        repo.Expect(x => x.ActivateFoo(foo)).
            Do(new ActivateFooDelegate(ActivateFooDelegateInstance));
        // act
        target.Activate(foo);

        // assert
        Assert.IsTrue(foo.IsActive);
        repo.VerifyAllExpectations();
    }

    private delegate bool ActivateFooDelegate(Foo f);

    public bool ActivateFooDelegateInstance(Foo f)
    {
        f.IsActive = true;
        return f.IsActive;
    }
0 голосов
/ 11 марта 2009

Я еще не использовал эту версию RhinoMocks, но в старых версиях вам пришлось бы использовать .Do (соответствующий делегат), чтобы установить флаг и вернуть значение (вместо .Return).

Пожалуйста, дайте мне знать, если это работает, если нет, я могу поиграть с этим.

...