Как получить доступ к защищенным членам базового класса во время модульного тестирования? - PullRequest
5 голосов
/ 28 ноября 2011

Я создаю модульный тест в mstest с использованием носорогов. У меня есть класс A, который наследует класс B. Я тестирую класс A и создаю его экземпляр для своего теста. Класс, который он наследует, «B», имеет некоторые защищенные методы и защищенные свойства, к которым я хотел бы получить доступ для моих тестов. Например, проверьте, что защищенное свойство в моем базовом классе имеет ожидаемое значение.

Есть идеи, как мне получить доступ к этим защищенным свойствам класса B во время моего теста?

Ответы [ 3 ]

6 голосов
/ 28 ноября 2011

Это неправильный подход с точки зрения модульного тестирования. Вы должны протестировать только открытый интерфейс и убедиться, что он ведет себя так, как ожидалось, вам не нужно заботиться о деталях реализации, таких как private / protected. Так что есть либо:

  • методы / свойства, которые вы собираетесь проверить, действительно должны быть общедоступными ИЛИ
  • Ваш тестовый пример / конкретная реализация теста неверны

EDIT:

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

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

2 голосов
/ 28 ноября 2011

Кроме того, другие ответы указывают в правильном направлении, если вам действительно нужно проверить, как вы описали, сделайте следующее:

Создайте класс TestA, который наследуется от A. Используйте это, чтобы сделать защищенные свойства B общедоступными для теста. Если у вас есть

class B {
    protected string Name {get; set;}
}

class A: B {
    public void DoSomething(string msg) {
        Name = msg.Trim();
    }
}

class TestA: A {
    public string GetName() {
        return Name;
    }
}

В вашем тесте теперь используйте TestA. Я не знаю синтаксис MsTest, но примерно это так:

[Test]
public void TestThatNameWasSet() {
    TestA systemUnderTest = new TestA();
    systemUnderTest.DoSomething("  new name  ");
    Assert.That(systemUnderTest.GetName(), Is.EqualTo("new name");
}
2 голосов
/ 28 ноября 2011

Ваши защищенные свойства должны влиять на некоторые аспекты публичного поведения вашего класса.

Тестировать это публичное поведение.

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

...