Rhino Mocks 3.3 Quick Reference
От: Aikin Беларусь kavaleu.ru
Дата: 31.10.08 09:12
Оценка: 36 (2)
Фреймворк для удобного создания мок-объектов для тестирования Rhino Mocks очень быстро развивается. Приходится довольно часто перечитывать документацию чтобы быть "в теме".

Сегодня как раз был такой день Залез на сайт и был несказанно рад тому, что есть Quick Refference 3.3 (всего на 3 странички) для быстрого вхождения (жаль что для версии 3,3 когда уже есть 3.5...).
Для тех кто совсем не пользовался RhinoMocks можно посмотреть Quick Refference 3.1 (всего 1 страничка, самое главное).

Вот цитаты:
Создание мока:
IConnection connection = mocks.CreateMock<IConnection>();

Использование using для разделения "зоны записи мока" от "зоны использования мока":
using (mocks.Record())
{ 
...    Expect.Call(...); 
}
using (mocks.Playback())
{
  ... 
}

Примеры установки ожиданий:
Expect.Call(list.Contains(42)).Return(true);
Expect.Call(dict.TryGetValue("key", out outParam)).OutRef("value").Return(true);

Запись ограничений на параметры:
Expect.Call(file.Read(null, 0, 0)) 
    .Constraints(Property.Value("Length", 4096), Is.Equal(0), Is.GreaterThan(0) && Is.LessThan(4096));



P.S. Еще есть описание версии 3.5 (и не только ее), но уже не совсем quick: http://ayende.com/wiki/Rhino+Mocks+3.5.ashx

СУВ, Aikin
Пример кода + презентация от Ayende
От: Aikin Беларусь kavaleu.ru
Дата: 31.10.08 09:37
Оценка: 2 (1)
Лежит тут: http://ayende.com/presentations.aspx

Солюшен и презентация: Interaction Based Testing &mdash; VB.Net (там не только VB? но и CS).
Re: Пример кода + презентация от Ayende
От: syrompe  
Дата: 05.11.08 14:09
Оценка:
Здравствуйте, Aikin, Вы писали:

A>Лежит тут: http://ayende.com/presentations.aspx


A>Солюшен и презентация: Interaction Based Testing &mdash; VB.Net (там не только VB? но и CS).



Также весьма интересные видео http://ayende.com/hibernating-rhinos.aspx
Re: Rhino Mocks 3.3 Quick Reference
От: ulu http://sm-art.biz
Дата: 14.11.08 21:47
Оценка: 6 (1)
Мне кажется, record-replay уже морально устарел: на дворе век Arrange-Act-Assert. По крайней мере, я сейчас потихоньку переключаюсь на это дело, и тесты становятся значительно чище и понятнее.

По поводу синтаксиса можно посмотреь блог ayende и группу google про rhino mocks.

ulu

Здравствуйте, Aikin, Вы писали:

A>Фреймворк для удобного создания мок-объектов для тестирования Rhino Mocks очень быстро развивается. Приходится довольно часто перечитывать документацию чтобы быть "в теме".


A>Сегодня как раз был такой день Залез на сайт и был несказанно рад тому, что есть Quick Refference 3.3 (всего на 3 странички) для быстрого вхождения (жаль что для версии 3,3 когда уже есть 3.5...).

A>Для тех кто совсем не пользовался RhinoMocks можно посмотреть Quick Refference 3.1 (всего 1 страничка, самое главное).

A>Вот цитаты:

A>Создание мока:
A>
A>IConnection connection = mocks.CreateMock<IConnection>();
A>

A>Использование using для разделения "зоны записи мока" от "зоны использования мока":
A>
A>using (mocks.Record())
A>{ 
A>...    Expect.Call(...); 
A>}
A>using (mocks.Playback())
A>{
A>  ... 
A>}
A>

A>Примеры установки ожиданий:
A>
A>Expect.Call(list.Contains(42)).Return(true);
A>Expect.Call(dict.TryGetValue("key", out outParam)).OutRef("value").Return(true);
A>

A>Запись ограничений на параметры:
A>
A>Expect.Call(file.Read(null, 0, 0)) 
A>    .Constraints(Property.Value("Length", 4096), Is.Equal(0), Is.GreaterThan(0) && Is.LessThan(4096));
A>



A>P.S. Еще есть описание версии 3.5 (и не только ее), но уже не совсем quick: http://ayende.com/wiki/Rhino+Mocks+3.5.ashx


A>СУВ, Aikin
Re[2]: Rhino Mocks 3.3 Quick Reference
От: cadet354 Россия
Дата: 28.11.08 12:33
Оценка:
Здравствуйте, ulu, Вы писали:

ulu>Мне кажется, record-replay уже морально устарел: на дворе век Arrange-Act-Assert. По крайней мере, я сейчас потихоньку переключаюсь на это дело, и тесты становятся значительно чище и понятнее.


что-то я не понял смысл Arrange-Act-Assert, можно поподробнее обьяснить, по примерам выходит тоже самое, что и в Moq.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Rhino Mocks 3.3 Quick Reference
От: ulu http://sm-art.biz
Дата: 28.11.08 19:02
Оценка: 2 (1)
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, ulu, Вы писали:


ulu>>Мне кажется, record-replay уже морально устарел: на дворе век Arrange-Act-Assert. По крайней мере, я сейчас потихоньку переключаюсь на это дело, и тесты становятся значительно чище и понятнее.


C>что-то я не понял смысл Arrange-Act-Assert, можно поподробнее обьяснить, по примерам выходит тоже самое, что и в Moq.


Наверное, похоже на Moq, я с ним не знаком.

Вот написал тут немного про свое видение вопроса здесь.
Re[4]: Rhino Mocks 3.3 Quick Reference
От: cadet354 Россия
Дата: 29.11.08 09:20
Оценка:
Здравствуйте, ulu, Вы писали:

спасибо, я так примерно и делал,( а какой был подход до этого), оказывается следовал веяниям моды ,
хотя вот этого:

Как все это организовать, чтобы было понятно? Начнем с последнего. Очень важный принцип, который я очень долго игнорировал (потому, что "все и так работало") -- надо в каждом тестовом методе иметь ровно один Assert. Более того, кроме него, в сущности, ничего там не должно быть. Все остальное безжалостно тащим в Сетап.

А что, если какой-то тестовый метод требует другого сетапа? Верный признак того, что он сидит не в своем тестовом классе. И тут включается другое правило -- На каждый тестовый класс должен быть один общий Act. То есть, мы каждый раз в Сетапе производим тестируемое действие, а потом в тестовых методах проверяем его эффекты. Это абсолютно противоположно новичковому методу, в котором тестовый метод содержит подготовку контекста, действие, а потом проверку многочисленных результатов.

у меня не было, действительно в методах проверка многочисленных результатов, но не приведет ли предлагаемый метод к лавинообразному увеличению количества тестов на ровном месте?
Re[5]: Rhino Mocks 3.3 Quick Reference
От: ulu http://sm-art.biz
Дата: 29.11.08 18:32
Оценка: -1
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, ulu, Вы писали:


C>спасибо, я так примерно и делал,( а какой был подход до этого), оказывается следовал веяниям моды ,

C>хотя вот этого:
C>

C>Как все это организовать, чтобы было понятно? Начнем с последнего. Очень важный принцип, который я очень долго игнорировал (потому, что "все и так работало") -- надо в каждом тестовом методе иметь ровно один Assert. Более того, кроме него, в сущности, ничего там не должно быть. Все остальное безжалостно тащим в Сетап.

C>А что, если какой-то тестовый метод требует другого сетапа? Верный признак того, что он сидит не в своем тестовом классе. И тут включается другое правило -- На каждый тестовый класс должен быть один общий Act. То есть, мы каждый раз в Сетапе производим тестируемое действие, а потом в тестовых методах проверяем его эффекты. Это абсолютно противоположно новичковому методу, в котором тестовый метод содержит подготовку контекста, действие, а потом проверку многочисленных результатов.

C>у меня не было, действительно в методах проверка многочисленных результатов, но не приведет ли предлагаемый метод к лавинообразному увеличению количества тестов на ровном месте?

В том-то и дело, что здесь место неровное. Юнит тест -- он не потому юнит, что проверяет функциональность какого-то одного небольшого куска системы, а потому, что он проверяет небольшой кусок функциональности. В идеале, посмотрев на название теста (и заменив подчеркивания на пробелы), можно получить кусочек ТЗ (и отрапортовать клиенту о его готовности):

[TestFixture] public class Если_нажать_на_красную_кнопку {
[Setup] public void Жмем_кнопку() {...}
[Test] public void Появится_сообщение() {...}
[Test] public void Текст_появившегося_сообщения__больше_не_жми() {...}
}

"Лавинообразное увеличение количества тестов" -- на самом деле, количество ассертов сохраняется, просто они разбегаются по разным методам.

Есть тут другая опасность -- когда ассерты взаимозависимы. Например, мы изготавливаем коллекцию, потом проверяем, что у нее только один элемент, а потом начинаем проверять свойства этого элемента. Если что-то сломалось, и в коллекции стало ноль элементов, то все ассерты сломаются, и мы увидим кучу красных кружочков, хотя на самом деле сломался только один тест. Это называется "эффектом домино". Выход есть: в MbUnit, например, можно задать явную зависимость тестов: если один не сработал, остальные не запускаются.
Re[6]: Rhino Mocks 3.3 Quick Reference
От: Ziaw Россия  
Дата: 01.12.08 09:58
Оценка:
Здравствуйте, ulu, Вы писали:

Что вообще дает такой подход? Какие плюсы?

Допустим тестриуемый метода должен запросить два числа из разных источников и выдать их сумму. Мне нужно сделать три теста (запросил число из одного источника, запросил из другого, вернул сумму)? Чем это будет лучше одного теста? Чем хуже понятно, нам надо писать три теста вместо одного и 3 раза вызывать тестируемый метод.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[7]: Rhino Mocks 3.3 Quick Reference
От: Aikin Беларусь kavaleu.ru
Дата: 01.12.08 10:16
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

Z>Что вообще дает такой подход? Какие плюсы?

Модульнось. SRP. Распределением ответственности.

Z>Допустим тестриуемый метода должен запросить два числа из разных источников и выдать их сумму.

Z>Мне нужно сделать три теста (запросил число из одного источника, запросил из другого, вернул сумму)?
Правильно, так и будет.
Z>Чем это будет лучше одного теста? Чем хуже понятно, нам надо писать три теста вместо одного и 3 раза вызывать тестируемый метод.
А почему тест который проверяет сумму двух чисел должен заморачиваться на то откуда они взялись?

И скажи, вот твой тест упал. Что именно пошло не так? Получение первого числа, второго, или сумматор глюканул?

СУВ, Aikin
Re[8]: Rhino Mocks 3.3 Quick Reference
От: Ziaw Россия  
Дата: 01.12.08 11:04
Оценка:
Здравствуйте, Aikin, Вы писали:

Z>>Что вообще дает такой подход? Какие плюсы?

A>Модульнось. SRP. Распределением ответственности.

А без лозунгов?

Z>>Чем это будет лучше одного теста? Чем хуже понятно, нам надо писать три теста вместо одного и 3 раза вызывать тестируемый метод.

A>А почему тест который проверяет сумму двух чисел должен заморачиваться на то откуда они взялись?

Тест проверяет то, что должен сделать метод. Метод должен сделать 3 вещи:
Взять из одного сервиса число a. Взять из другого число b. Сложить их и вернуть результат.

    public interface INumberSource
    {
        int GetNumber();
    }

    public class SomeService
    {
        private readonly INumberSource aSource;
        private readonly INumberSource bSource;

        public SomeService(INumberSource aSource, INumberSource bSource)
        {
            this.aSource = aSource;
            this.bSource = bSource;
        }

        public int SomeMethod()
        {
            return aSource.GetNumber() + bSource.GetNumber();
        }
    }

    [TestFixture]
    public class SomeServiceTests
    {

        MockRepository repos;
        INumberSource aSrcMock;
        INumberSource bSrcMock;
        SomeService service;

        [SetUp]
        public void Setup()
        {
            repos = new MockRepository();
            aSrcMock = repos.CreateMock<INumberSource>();
            bSrcMock = repos.CreateMock<INumberSource>();
            service = new SomeService(aSrcMock, bSrcMock);
        }

        [Test]
        public void SomeMethodTest()
        {
            using (repos.Record())
            {
                Expect.Call(aSrcMock.GetNumber()).Return(1);
                Expect.Call(bSrcMock.GetNumber()).Return(2);
            }

            using (repos.Playback())
            {
                var result = service.SomeMethod();
                Assert.AreEqual(3, result);
            }
        }
    }


Как будут выглядеть 3 теста? Чем они удобнее одного?

A>И скажи, вот твой тест упал. Что именно пошло не так? Получение первого числа, второго, или сумматор глюканул?

Тест при падении говорит, какой ассерт не сработал. Этого достаточно.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[8]: Rhino Mocks 3.3 Quick Reference
От: ulu http://sm-art.biz
Дата: 01.12.08 11:10
Оценка:
Здравствуйте, Aikin, Вы писали:

A>Здравствуйте, Ziaw, Вы писали:


Z>>Что вообще дает такой подход? Какие плюсы?

A>Модульнось. SRP. Распределением ответственности.

Z>>Допустим тестриуемый метода должен запросить два числа из разных источников и выдать их сумму.

Z>>Мне нужно сделать три теста (запросил число из одного источника, запросил из другого, вернул сумму)?
A>Правильно, так и будет.
Z>>Чем это будет лучше одного теста? Чем хуже понятно, нам надо писать три теста вместо одного и 3 раза вызывать тестируемый метод.
A>А почему тест который проверяет сумму двух чисел должен заморачиваться на то откуда они взялись?

A>И скажи, вот твой тест упал. Что именно пошло не так? Получение первого числа, второго, или сумматор глюканул?


A>СУВ, Aikin


+1.

Если не хочется вызывать метод 3 раза, то можно отправить его в FixtureSetup. Но там лучше держать Arrange.
Re[9]: Rhino Mocks 3.3 Quick Reference
От: Ziaw Россия  
Дата: 01.12.08 11:50
Оценка:
Здравствуйте, ulu, Вы писали:

ulu>+1.


Я так и не услышал плюсов подхода, только баззворды. И не увидел примера теста SomeService
Автор: Ziaw
Дата: 01.12.08
.

ulu>Если не хочется вызывать метод 3 раза, то можно отправить его в FixtureSetup. Но там лучше держать Arrange.


Т.е. на каждый метод тестируемого класса мы делаем свой TestFixture? Не слишком ли жирно? Плюсы подхода должны быть просто громадными, чтобы оправдать такое.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[9]: Rhino Mocks 3.3 Quick Reference
От: Aikin Беларусь kavaleu.ru
Дата: 01.12.08 11:51
Оценка:
Здравствуйте, Ziaw, Вы писали:

Начнем с того, что ulu говорит совсем про другое. Про реорганизацию тестов, а не про бессмысленное увеличение их количества.
И с того, что я тебя неправильно понял. Я считал, что тестиреумый метод сам занимается получением этих двух чисел.

Z>Тест проверяет то, что должен сделать метод. Метод должен сделать 3 вещи:

Z>Взять из одного сервиса число a. Взять из другого число b. Сложить их и вернуть результат.
C чего ты взял, что ulu предлагал на разбить функциональность из 3-х шагов (1 ассерт) на три теста (3 ассерта)?

Z>Как будут выглядеть 3 теста? Чем они удобнее одного?

То что ты написал это третий тест То что "Expect.Call(...)" является еще и ассертом -- дополнительный плюс Мок-тестирования (чесно говоря, спорный плюс).
Первый тест будет проверять FirstConcreteNumberSource, а второй -- SecondConcreteNumberSource

СУВ, Aikin
Re[10]: Rhino Mocks 3.3 Quick Reference
От: Aikin Беларусь kavaleu.ru
Дата: 01.12.08 11:56
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Т.е. на каждый метод тестируемого класса мы делаем свой TestFixture?

Не на каждый метод, а на каждое состояние тестируемого объекта.

Z> Не слишком ли жирно? Плюсы подхода должны быть просто громадными, чтобы оправдать такое.

У меня тоже есть сомнения.
Re[10]: Rhino Mocks 3.3 Quick Reference
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.08 12:02
Оценка:
Здравствуйте, Aikin, Вы писали:

A>Здравствуйте, Ziaw, Вы писали:


Z>>Как будут выглядеть 3 теста? Чем они удобнее одного?

A>То что ты написал это третий тест То что "Expect.Call(...)" является еще и ассертом -- дополнительный плюс Мок-тестирования (чесно говоря, спорный плюс).
Да, потому с версии 3.5 предпочтительнее является использование стабов. Ведь третий тест не должен проверять, что методы Expect.Call действительно были вызываны. И Expect.Call здесь просто информирует мокоген о том, что нужно вернуть. При использовании стабов информация о результатах используется, но факт вызова метода не проверяется.

A>Первый тест будет проверять FirstConcreteNumberSource, а второй -- SecondConcreteNumberSource

А вот это уже похоже на тестирование реализации метода. Что если SomeService не обязан вызывать эти методы в реализации метода SomeMethod? Возможно он закэшировал нужные значения в конструкторе? Т.е. проверяя факты вызова тех методов мы проверяем вовсе не контракт метода.
Re[11]: Rhino Mocks 3.3 Quick Reference
От: Ziaw Россия  
Дата: 01.12.08 12:11
Оценка:
Здравствуйте, Aikin, Вы писали:

Z>>Т.е. на каждый метод тестируемого класса мы делаем свой TestFixture?

A>Не на каждый метод, а на каждое состояние тестируемого объекта.

Состояние по сути является по сути еще одним аргументом к тестируемому методу. Мне трудно понять, чем оно отличается от других аргументов.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[11]: Rhino Mocks 3.3 Quick Reference
От: Aikin Беларусь kavaleu.ru
Дата: 01.12.08 12:12
Оценка:
Здравствуйте, samius, Вы писали:

Z>>>Как будут выглядеть 3 теста? Чем они удобнее одного?

A>>То что ты написал это третий тест То что "Expect.Call(...)" является еще и ассертом -- дополнительный плюс Мок-тестирования (чесно говоря, спорный плюс).
S>Да, потому с версии 3.5 предпочтительнее является использование стабов. Ведь третий тест не должен проверять, что методы Expect.Call действительно были вызываны. И Expect.Call здесь просто информирует мокоген о том, что нужно вернуть. При использовании стабов информация о результатах используется, но факт вызова метода не проверяется.
Угу.

A>>Первый тест будет проверять FirstConcreteNumberSource, а второй -- SecondConcreteNumberSource

S>А вот это уже похоже на тестирование реализации метода. Что если SomeService не обязан вызывать эти методы в реализации метода SomeMethod? Возможно он закэшировал нужные значения в конструкторе? Т.е. проверяя факты вызова тех методов мы проверяем вовсе не контракт метода.
Эти два теста будут находится среди тестов для FirstConcreteNumberSource и SecondConcreteNumberSource и никак не относится к SomeService
Re[12]: Rhino Mocks 3.3 Quick Reference
От: Aikin Беларусь kavaleu.ru
Дата: 01.12.08 12:16
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>>>Т.е. на каждый метод тестируемого класса мы делаем свой TestFixture?

A>>Не на каждый метод, а на каждое состояние тестируемого объекта.
Z>Состояние по сути является по сути еще одним аргументом к тестируемому методу. Мне трудно понять, чем оно отличается от других аргументов.
С этим сложно спорить. Хотя это и не совсем так. Раз "парамеры" находятся в разных местах (в объекте и аргументах метода), то это кому-то надо.


Вопрос: У тебя в одном тесте проверяется вызов метода с разными значениями параметров?
Re[13]: Rhino Mocks 3.3 Quick Reference
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.08 12:26
Оценка:
Здравствуйте, Aikin, Вы писали:

A>Здравствуйте, Ziaw, Вы писали:


Z>>>>Т.е. на каждый метод тестируемого класса мы делаем свой TestFixture?

A>>>Не на каждый метод, а на каждое состояние тестируемого объекта.
Z>>Состояние по сути является по сути еще одним аргументом к тестируемому методу. Мне трудно понять, чем оно отличается от других аргументов.
A>С этим сложно спорить. Хотя это и не совсем так. Раз "парамеры" находятся в разных местах (в объекте и аргументах метода), то это кому-то надо.


A>Вопрос: У тебя в одном тесте проверяется вызов метода с разными значениями параметров?

Вопрос не ко мне, но я свою копейку вверну:
MbUnit умеет делать параметризованные тесты, куда можно прикручивать атрибутами либо комбинации параметров, либо провайдеры параметров. Фактически тело метода одно, но тесты создаются разные — по числу комбинаций параметров либо провайдеров.
Потому да, бывает что один метод проверяет вызов метода с разными значениями, но это физически разные тесты!
Новый NUnit тоже позволяет делать тесты с параметрами, только я еще не глядел на него пока и не знаю, трактует ли он их как разные тесты, либо как один.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.