Moh Rhino: AAA Synax: свойство Assert было задано с заданным типом - PullRequest
2 голосов
/ 18 марта 2011

Я пытаюсь утверждать, что свойство в фиктивном объекте было установлено с заданным типом.Свойство имеет абстрактный тип и задается с одним из нескольких конкретных типов.

Это то, что я пытаюсь сделать, и оно всегда проходит тест независимо от значения, которое Foo.DoSomething ()устанавливает Foo.Bar с:

    [Test]
    public void DoSomething_SetsCorrectBar()
    {
        // Arrange
        Foo foo = MockRepository.GenerateMock<Foo>(); // Creates mock in Replay mode (what I want for AAA syntax).

        // Act
        foo.DoSomething();

        // Assert that DoSomething set Foo.Bar to an instance of CorrectBarSubclass
        foo.AssertWasCalled(foo => foo.Bar = null, options => options.WhenCalled(invocation => Assert.That(invocation.Arguments[0] is CorrectBarSubclass)));
    }

Документация Rhino 3.5 / AAA описывает, как устанавливать ожидания для наборов свойств, имеющих заданное значение, но я просто хочу проверить типзначение.

Как можно утверждать о наборе свойств, в частности, о наборе свойств, имеющем данный тип параметра?


Обновление: Приведенный выше пример упрощен,То, что я на самом деле тестирую, это отдельный государственный класс.Это одно из нескольких состояний, в котором может находиться «родительский объект» (объект, имеющий состояние, в данном случае Foo). Я проверял, что тестируемое состояние (называемое BarOne) правильно устанавливает Foo.State для экземпляра BarTwoкогда пришло время переходных состояний.

Более понятный пример (с реализованным принятым решением) будет:

    [Test]
    public void BarOne_DoSomething_SetsNextState()
    {
        // Arrange
        Foo foo = MockRepository.GenerateMock<Foo>(); // Creates mock in Replay mode (what I want for AAA syntax).
        foo.Stub(x => x.CreateBarTwoState()).Return(new BarTwo(foo));
        BarOne bar = new BarOne(foo); // We are testing the BarOne state independently of Foo, that's why we mock Foo but instantiate BarOne.

        // Act
        bar.DoSomething();

        // Assert that DoSomething set Foo.Bar to an instance of BarTwo
        foo.AssertWasCalled(foo => foo.Bar = Arg<BarTwo>.Is.TypeOf);
    }

Ответы [ 2 ]

4 голосов
/ 18 марта 2011

Возможно что-то вроде этого:

[Test]
public void AddPlayer_GivesGameEnoughPlayersToStart_SetsNextState()
{
    // Arrange
    Foo foo = MockRepository.GenerateMock<Foo>(); // Creates mock in Replay mode (what I want for AAA syntax).
    foo.Expect(m => m.Bar = Arg<CorrectBarSubclass>.Is.TypeOf);
    // Act
    foo.DoSomething();
    //Assert
    foo.VerifyAllExpectations();
}

Итак, что происходит ..

Мы изменили утверждение на Ожидание. Я считаю, что это немного чище, и ожидание позволяет нам более четко проверить, что это за тип. Мы говорим: «Ожидаем, что для Bar будет установлен экземпляр CorrectBarSubclass. Затем мы действуем и утверждаем, что наши ожидания оправдались.

Пара вещей: Каждый раз, когда вы макетируете класс, все, что у вас есть на вызове Expect или Stub, должно быть виртуальным или абстрактным, поэтому в этом случае Bar должно быть виртуальным. Обычно всегда лучше смоделировать интерфейс и проверить, как класс использует зависимость, а не тестировать, как класс использует сам себя (это обычно является признаком чрезмерного тестирования или неправильного разделения проблем).

В вашем случае, издевательство вообще требуется? Вы просто используете несколько сложный синтаксис, чтобы утверждать результат реального поведения, на самом деле ничто не является насмешкой, кроме установщика свойства. Иногда проще и уместнее проверить реальное поведение. Почему бы не сделать что-то вроде этого:

var foo = new Foo();
foo.DoSomething();
Assert.That(foo.Bar is CorrectBarSubclass);
3 голосов
/ 16 ноября 2012

У меня была похожая проблема, когда я пытался заглушить выражение предиката для Find-метода, который содержит строку (которая, конечно, неизменна).Безуспешно, пока я не создаю testPredicate, который я передаю заглушке, фактическому SUT и, наконец, утверждаю.Код ниже работает.

    [Test()]
    public void Search_Apartment_With_Spesific_Address()
    {
        //ARRANGE
        var repositoryMock = MockRepository.GenerateMock<IApartmentRepository>();
        var notificationMock = MockRepository.GenerateMock<INotificationService>();
        var service = new ApartmentService(repositoryMock, notificationMock);
        var apartment = new List<Apartment> {new Apartment {Address = "Elm Street 2"}}.AsQueryable();

        Expression<Func<Apartment, bool>> testPredicate = a => a.Address == "Elm Street 2";
        repositoryMock.Stub(x => x.Find(testPredicate)).Return(apartment);

        //ACT
        service.Find(testPredicate);

        //ASSERT
        repositoryMock.AssertWasCalled(x => x.Find(testPredicate));
    }

РЕДАКТИРОВАТЬ: этот ответ был исправлен и отправлен для исправления вопроса-заглушки IQueryable.

...