Пересылка без сгенерированного кода для тестирования частных методов - PullRequest
2 голосов
/ 25 июня 2009

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

Однако в настоящее время я имею дело с кодовой базой, в которой есть несколько областей, которые стали зависеть от [механизма закрытого доступа в VSTS] (http://msdn.microsoft.com/en-us/library/ms184807(VS.80).aspx) (то есть, используя VSCodeGenAccessors для генерации *_Accessor классы с переадресацией, использующие отражение, для вызова private членов (и, возможно, internal членов) в классе.

Итак, у меня есть такой код:

ClassUnderTest target = new ClassUnderTest();
var accessor = ClassUnderTest_Accessor.AttachShadow( target );
accessor.PrivateMethod();
Assert.True( accessor._privateMethodWasCalled);
accessor.PrivateProperty = 5;
Assert.Equal( accessor.PrivateProperty, 5);

(Да, изобилует антипаттернами, но, пожалуйста, не стреляйте в мессенджера)

У меня есть ряд проблем с этим:

  1. Я бы хотел уточнить, что мне нужно,
  2. Я бы предпочел не вызывать диалоги (да, я карахолик)
  3. Я бы предпочел не включать генерацию кода на картинке

Так что я хотел бы иметь возможность преобразовать приведенный выше код в что-то вроде:

var target = new ClassUnderTest();
IClassUnderTestInterface accessor = Shadow.Create<IClassUnderTestInterface>( target );
accessor.PrivateMethod();
Assert.True( accessor._privateMethodWasCalled);
accessor.PrivateProperty = 5;
Assert.Equal( accessor.PrivateProperty, 5);

В моей тестовой сборке только следующий интерфейс, без сгенерированного кода или пользовательских шагов сборки: -

interface IClassUnderTestInterface
{
   int PrivateProperty {get; set;}
   bool _privateMethodWasCalled {get; }
   void PrivateMethod();
}

Оттуда я смогу использовать CodeRush или Ctrl K M для генерации новых теневых методов на интерфейсе только нажатием клавиши.

Отсутствующий бит будет иметь метод I Shadow.Create<I>( Object o), который будет 1. создать динамический прокси, который реализует интерфейс 1. убедитесь, что обертываемый объект o содержит все элементы, определяемые интерфейсом 1. bnous: правильно управлять пересылкой свойств, представляющих поля (т. Е. Случай «_privateMethodWasCalled»)

Итак, кто-нибудь знает библиотеку, которая реализует что-то подобное (или скучает достаточно, чтобы написать это?)

Один очевидный недостаток заключается в том, что вы не знаете, несовместим ли интерфейс с ClassUnderTest до времени выполнения, но это нормально, так как это будет только для тестов. Кроме того, AIUI, механизм приватных средств доступа, также требует запуска перекомпиляции для синхронизации данных время от времени.

Или есть способ лучше подойти, которого мне не хватает? (Помня, что я не хочу полностью унифицировать внутренние или публичные аккаунты и не хочу переписывать рабочий код)

Использование xUnit.net, .NET 3.5; Открыто для использования любой динамической прокси-библиотеки или другой

Ответы [ 3 ]

1 голос
/ 26 ноября 2009

В конечном итоге я обошел все эти вещи (InternalsVisibleTo, отдельные тестовые проекты, тестовые ссылки, частные средства доступа, задача MSBuild Shadow / publicize.exe, которая не выполнялась случайным образом в сборках с использованием отражения для доступа к частным лицам) путем объединения тестов в основные проекты и изготовление всего, что нужно было получить из тестов internal). См. Также xUnit.net Test Stripper [для удаления тестового кода, встроенного в двоичные файлы перед развертыванием / отправкой]

1 голос
/ 26 июня 2009

Вы смотрели на насмешливые фреймворки, такие как Moq или Rhino? В вашем случае они могут помочь, ЕСЛИ вы готовы сменить рядовых лиц, которых вам необходимо протестировать, на «защищенный виртуальный» (что не так уж плохо для публики внутреннего). По сути, если член является виртуальным, тогда среда моделирования может генерировать подкласс, который записывает, какие члены называются.

0 голосов
/ 12 февраля 2010

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

Кроме того, этот ответ описывает, как обрабатывать static участников (но требует CLR4, который не был в игре во время моего запроса и не обрабатывает приватные методы без добавления InternalsVisibleTo в микс ).

...