В общем, я разрабатываю классы таким образом, чтобы не требовать доступа к частным лицам в целях тестирования. 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);
(Да, изобилует антипаттернами, но, пожалуйста, не стреляйте в мессенджера)
У меня есть ряд проблем с этим:
- Я бы хотел уточнить, что мне нужно,
- Я бы предпочел не вызывать диалоги (да, я карахолик)
- Я бы предпочел не включать генерацию кода на картинке
Так что я хотел бы иметь возможность преобразовать приведенный выше код в что-то вроде:
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; Открыто для использования любой динамической прокси-библиотеки или другой