RhinoMocks и Heisenbugs

В последнее время я использую RhinoMocks, но постоянно сталкиваюсь с проблемой. Если я взломаю отладчик и перейду через код, пока макет находится в режиме записи, я получаю исключение в следующих строках:

System.InvalidOperationException: Previous method 'SuchAndSuch.ToString();'  
requires a return value or an exception to throw.

Но если я выполню тот же код, не взламывая отладчик, он выполнится успешно и создаст макет.

Я почти уверен, что причина этого в том, что отладчик вызывает ToString () для объектов, чтобы отобразить их в окнах Locals и других окнах Watch. Но поскольку макет находится в режиме записи, RhinoMocks считает вызов ToString () установкой ожиданий, что в таком случае не совсем корректно. Очевидно, это происходит только с частичными имитами конкретных классов. Моки против интерфейсов не демонстрируют такого поведения.

Сталкивались ли другие люди с этой проблемой? Есть какое-нибудь простое средство? Есть ли эта проблема в других фреймворках, таких как moq или TypeMock?

Спасибо,

~ Джастин


person RationalGeek    schedule 11.03.2010    source источник


Ответы (2)


Я помню, как много лет назад у меня была похожая проблема с NMock. По сути, эта проблема возникает именно потому, что отладчик вызывает и отображает свойства с помощью метода ToString (если вы не используете DebuggerDisplayAttribute или аналогичный).

Это может быть особенно проблематично, если вы используете строгие моки, потому что они позволяют вам вызывать член только указанное количество раз, и отладчик вмешивается в это. Использование свободных макетов решает эту (и многие другие) проблемы.

Вы также можете отказаться от механизма записи / воспроизведения Rhino Mocks и начать использовать новый и гораздо лучший лямбда-синтаксис.

Moq использует синтаксис lamda (почти) исключительно, и у меня никогда не было таких проблем с ним, но опять же, в наши дни я мало отлаживаю, поскольку модульные тесты стали заменой отладки.

Еще одно средство - просто скрыть окна отладчика Авто и Локальные переменные.

person Mark Seemann    schedule 11.03.2010
comment
Спасибо за информацию. Я не видел синтаксиса лямбда. У вас есть ссылка на хорошую отправную точку, чтобы узнать об этом? - person RationalGeek; 11.03.2010
comment
Вот исходное объявление: ayende.com/Blog/archive/2008/05/16/ - person Mark Seemann; 11.03.2010
comment
Его также часто называют синтаксисом AAA: ayende.com/Wiki/Rhino+Mocks+3.5 .ashx - person Mark Seemann; 11.03.2010
comment
Спасибо за ссылки. Что касается вашего потенциального решения, мне не удалось просто скрыть Autos и Locals. Я думаю, что отладчик все еще выполняет ToString (), даже когда они скрыты. - person RationalGeek; 11.03.2010
comment
Принято как ответ. Он не решает проблему heisenbug напрямую, но является альтернативой. - person RationalGeek; 12.03.2010

Как предположил Марк, эта проблема должна исчезнуть, если вы перестанете использовать подход «запись-воспроизведение-проверка» и вместо этого начнете использовать заглушки с рекомендуемым подходом AAA (упорядочить, действовать, утверждать).

Я попытался объяснить разницу и то, как это сделать с помощью Rhino Mocks, в этом запись в блоге.

person Wim Coenen    schedule 11.03.2010
comment
На мой взгляд, AAA не противоречит записи-воспроизведению-проверке; скорее, он просто описывает общую организацию теста, любого теста, с использованием или без использования имитирующего API. Record-replay-verify просто описывает организацию тестов, в которых используется API-интерфейс, ориентированный на поведение, где ожидания могут быть записаны, затем воспроизведены и, наконец, проверены. - person Rogério; 06.10.2010