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

Я пытаюсь использовать InternalsVisibleTo чтобы я мог протестировать служебный / вспомогательный метод из отдельной тестовой сборки. Когда я пытаюсь вызвать метод internal с параметр динамический Я получаю сообщение об ошибке "Не удалось обработать исключение RuntimeBinderException ... недоступен из-за уровня защиты. "

Я считаю, что использую атрибут InternalsVisibleTo правильно, поскольку я могу протестировать другие внутренние методы, которые не используют dynamic параметры. Следующий код иллюстрирует сценарий, в котором не удается выполнить только тест TestInternalMethodWithDynamic, как показано ниже. Я повторил тесты, используя методы экземпляра вместо статических, и это не имело никакого значения.

Технология .NET - это Silverlight 5, и я использую Silverlight Unit Test Framework для выполнения тестов. Мне нужно использовать динамические параметры из-за требований автоматизации проекта Excel.

Изменить: я протестировал тот же вызов, используя сборки библиотеки классов .NET 4, и он прошел успешно, поэтому проблема, похоже, специфична для Silverlight.

Результаты модульного тестирования Silverlight

Пример служебного класса ...

public class Utility
{
    internal static int InternalMethodWithDynamic(dynamic parameter) {
        return (int)parameter;
    }

    internal static int InternalMethodWithInteger(int parameter) {
        return parameter;
    }

    public static int PublicMethodWithDynamic(dynamic parmater) {
        return (int)parmater;
    }

    public static int PublicMethodWithInteger(int parmater) {
        return parmater;
    }
}

И тестовый класс ...

[TestClass]
public class UtilityTest
{
    [TestMethod]
    public void TestInternalMethodWithDynamic() {
        dynamic parameter = 10;
        Assert.AreEqual(10, Utility.InternalMethodWithDynamic(parameter));
    }

    [TestMethod]
    public void TestPublicMethodWithInteger() {
        int parameter = 10;
        Assert.AreEqual(10, Utility.PublicMethodWithInteger(parameter));
    }

    [TestMethod]
    public void TestPublicMethodWithDynamic() {
        dynamic parameter = 10;
        Assert.AreEqual(10, Utility.PublicMethodWithDynamic(parameter));
    }

    [TestMethod]
    public void TestInternalMethodWithInteger() {
        int parameter = 10;
        Assert.AreEqual(10, Utility.InternalMethodWithInteger(parameter));
    }
}

person Martin Hollingsworth    schedule 19.04.2013    source источник
comment
К вашему сведению, я не мог воспроизвести это с помощью простого консольного приложения + библиотеки классов. Я использовал .NET 4.5, не уверен, что это имеет значение.   -  person Matt Smith    schedule 19.04.2013
comment
Вы, должно быть, пропустили мою правку, в которой я добавил, что пробовал использовать библиотеки классов .NET 4, и все прошло нормально. Как я сказал при редактировании, я почти уверен, что это проблема Silverlight. Тем не менее, спасибо за подтверждение на .NET 4.5. @MattSmith   -  person Martin Hollingsworth    schedule 19.04.2013
comment
Ах да, пропустил. Интересная проблема +1.   -  person Matt Smith    schedule 19.04.2013


Ответы (1)


Временное решение:

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

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

[TestClass]
public class UtilityTest
{
    [TestMethod]
    public void TestInternalMethodWithDynamic() {
        int parameter = 10;
        Assert.AreEqual(10, Utility.InternalMethodWithDynamic(parameter));
    }
}
person Martin Hollingsworth    schedule 19.04.2013