Как издеваться над внутренним методом класса? - PullRequest
20 голосов
/ 05 мая 2010

У меня есть класс, который имеет внутренний метод, и я хочу издеваться над внутренним методом. Но я не могу его смоделировать, т. Е. Он вызывает не проверенную функцию, а исходную функцию. Есть ли способ добиться этого?

Редактировать: На самом деле я новичок в Мок. У меня есть много классов и методов классов для тестирования с помощью Moq. Многие классы являются внутренними, многие имеют внутренние методы, многие имеют не виртуальные методы. И не может изменить подпись на методах и классах. Может кто-нибудь, пожалуйста, дайте мне знать, как пройти тестирование этого сценария с помощью Moq. Или же, пожалуйста, предложите мне какую-нибудь другую среду тестирования, с которой легко учиться и с которой легко работать.

Ответы [ 6 ]

60 голосов
/ 13 мая 2010

Вы можете легко смоделировать внутренние виртуальные методы, добавив в файл AssemblyInfo.cs следующее:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // namespace in Moq
[assembly: InternalsVisibleTo("YourTestClass")]

Если ваша сборка имеет строгое имя, вам необходимо включить открытый ключ для DynamicProxyGenAssembly2 (Благодаря комментарию @bvgheluwe; источник: Moq краткое руководство ) :

[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

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

27 голосов
/ 25 августа 2010

Отметьте метод как internal *protected* (также, конечно, виртуальный)

3 голосов
/ 05 мая 2010

Не с Мок.

Но вы можете использовать бесплатный фреймворк Moles от MS, чтобы делать такие вещи. Я написал об этом здесь: Насмешка над немодным: Использование Microsoft Moles с Gallio . (это относится не только к Галлио, но и дает хорошее общее представление о том, что вы можете делать с родинками ...). Другой альтернативой будет Typemock ...

НТН. Томас

1 голос
/ 05 мая 2010

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

Если вы чувствуете, что необходимо изменить метод, чтобы сделать класс тестируемым, выполните рефакторинг класса, чтобы сложная часть стала зависимостью или была заменена другим способом с помощью параметра или подкласса.

1 голос
/ 05 мая 2010

Почему вы хотите издеваться над внутренним методом?

Если вы обнаружите необходимость смоделировать внутренний метод, скажем, чтобы обойти зависимость или взаимодействие, вам, возможно, следует подумать о редизайне класса.

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

Я не верю, что есть четкий путь к непубличной насмешке с Moq.

Но, если вам абсолютно необходимо, вы можете использовать TypeMock Isolator , чтобы издеваться над чем угодно.

Кроме того, чтобы не затеряться в грохоте: Томас написал хорошую статью об использовании бесплатных MS Moles для насмешек над непубличными участниками.

Насмешка над немытым: Использование Microsoft Moles с Gallio

0 голосов
/ 05 мая 2010

Если вам нужно протестировать большое количество кода, который вы не можете изменить, лучше с самого начала использовать MS Moles или TypeMock.

Бесплатные фреймворки, такие как Moq, в любом случае, поддерживают только интерфейсы и виртуальные методы. Не звучит так, как будто вы далеко пойдете с этим ...

Thomas

...