Сделать код внутренним, но доступным для модульного тестирования из других проектов.

StackOverflow https://stackoverflow.com/questions/106907

  •  01-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

Если вы используете .NET, ВнутренностиVisibleTo Атрибут сборки позволяет создавать «дружественные» сборки.Это конкретные сборки со строгими именами, которым разрешен доступ к внутренним классам и членам другой сборки.

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

Пример:

[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{

Другие советы

Если это внутренний класс, его нельзя использовать изолированно.Поэтому вам не следует тестировать его отдельно от тестирования какого-либо другого класса, который использует этот объект внутри себя.

Точно так же, как вам не следует тестировать частные члены класса, вам не следует тестировать внутренние классы DLL.Эти классы являются деталями реализации какого-либо общедоступного класса, и поэтому их следует тщательно отрабатывать с помощью других модульных тестов.

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

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

для целей документации

в качестве альтернативы вы можете создать экземпляр внутреннего класса, используя Type.GetType метод

пример

//IServiceWrapper is public class which is 
//the same assembly with the internal class 
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
    .CreateInstance(type, new object[1] { /*constructor parameter*/ });

для общего типа существуют разные процессы, как показано ниже:

var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
     .CreateInstance(genType, new object[1] { /*constructor parameter*/});

Классы могут быть как общедоступными, так и запечатанными.

Но не делайте этого.

Вы можете создать инструмент для отражения внутренних классов и создать новый класс, который обращается ко всему через отражение.MSTest делает это.

Редактировать:Я имею в виду, если вы не хотите включать какие-либо тестовые материалы в исходную сборку;это также работает, если участники являются частными.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top