NMock2.0 - как заглушить не интерфейсный вызов? - PullRequest
5 голосов
/ 19 февраля 2010

У меня есть API класса, который имеет полное покрытие кода и использует DI для макетирования всей логики в функции основного класса (Job.Run), которая выполняет всю работу.

Я обнаружил ошибку в работегде мы не выполняли некоторую проверку для одного из полей ввода данных.

Итак, я добавил функцию-заглушку под названием ValidateFoo () ... Написал модульный тест для этой функции, чтобы ожидать исключение JobFailedException, запустил тест -он потерпел неудачу, очевидно, потому что эта функция была пустой.Я добавил логику проверки, и теперь тест проходит.

Отлично, теперь мы знаем, что проверка работает.Проблема в том, как мне написать тест, чтобы убедиться, что ValidateFoo () действительно вызывается из Job.Run ()?ValidateFoo () - это закрытый метод класса Job, так что это не интерфейс ...

Есть ли способ сделать это с NMock2.0?Я знаю, что TypeMock поддерживает подделки не интерфейсных типов.Но менять макеты библиотек прямо сейчас не вариант.На этом этапе, если NMock не может его поддерживать, я просто добавлю вызов ValidateFoo () в метод Run () и протестирую его вручную - что, очевидно, я бы предпочел не делать, учитывая, что мой метод Job.Run () имеет100% охват прямо сейчас.Любой совет?Большое спасибо, это ценится.

РЕДАКТИРОВАТЬ: другой вариант, который я имею в виду, - это просто создать интеграционный тест для моей функциональности Job.Run (внедряя в него истинные реализации составного кода).объекты вместо издевательств).Я введу неверное значение для этого поля и проверим, что задание не выполнено.Это работает и охватывает мой тест - но на самом деле это не модульный тест, а интеграционный тест, который проверяет одну функциональную единицу .... хм ..

РЕДАКТИРОВАТЬ2: Есть ли в любом случаеделать это?У кого-нибудь есть идеи?Может быть, TypeMock - или лучший дизайн?

Ответы [ 2 ]

5 голосов
/ 26 апреля 2010

Текущая версия NMock2 может макетировать конкретные типы (я точно не помню, какую версию они добавили, но мы используем версию 2.1), используя наиболее знакомый синтаксис:

Job job = mockery.NewMock<Job>(MockStyle.Transparent);
Stub.On(job).Method("ValidateFoo").Will(Return.Value(true));

MockStyle.Transparent указывает, что все, что вы не заглушаете или не ожидаете, должно обрабатываться базовой реализацией - так что вы можете заглушки и устанавливать ожидания для методов в тестируемом экземпляре.

Однако,Вы можете только заглушить и установить ожидания для открытых методов (и свойств), которые также должны быть виртуальными или абстрактными.Поэтому, чтобы не полагаться на интеграционное тестирование, у вас есть два варианта:

  • Сделать Job.ValidateFoo() общедоступным и виртуальным.
  • Извлечь логику проверки в новый класс и внедрить экземпляр в Job.
1 голос
/ 24 марта 2011

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

Я не вижу тестируемый класс. Другая проблема, которая может подтолкнуть вас к желанию получить доступ к закрытым методам, заключается в том, что это супер большой класс с множеством частных функций. Эти классы, возможно, придется разбить на более мелкие классы, и некоторые из этих рядовых могут превратиться в более простых людей.

...