2011-02-25 3 views
1

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

Мне нужно проверить конструктор моего класса, в конструкторе я устанавливаю экземпляр частного поля. Итак, как я могу проверить, не содержит ли это поле PRIVATE значение null? (Потому что я полагаю, что то, что я должен проверить) -> Для теста:

public BUDGET_MANAGER() 
    { 
     this.budget_provider = new BUDGET_PROVIDER(); 
    } 

-> Test Mehod:

[TestMethod()] 
    public void BUDGET_MANAGERConstructorTest1() 
    { 
     BUDGET_MANAGER target = new BUDGET_MANAGER();  
     Assert.IsNotNull(??,"the provider is not instancied"); 

    } 

Как я могу это сделать? Спасибо за помощь, я довольно потерян в модульном тестировании.

+1

См: http://msdn.microsoft.com/en-us/library /0tke9fxk.aspx (хотя вам нужно сделать поле 'internal' вместо' private', которое может и не быть тем, что вам нужно.) –

+0

Возможный дубликат [Unit testing and checking private variable value] (http://stackoverflow.com/questions/1093020/unit-testing-and-checking-private-variable-value) –

ответ

4

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

В принципе, подумайте о внешне видимых членах класса как о его «контракте». Это определяет его фактический тип, что видит все остальное. И это проверенная функциональность. Внутренние (частные) члены не известны за пределами класса по очень веской причине, другой класс может реализовать тот же «контракт» (или интерфейс) по-другому, с разными частными членами.

Что вы тестируете - это видимая функциональность, договор или интерфейс.

+0

Хорошо, так что ничего не проверить в моем случае? – bAN

+0

@bAN: зависит от класса. Если «тип» (интерфейс, подразумеваемый или явный) тесно связан с «классом» (реализация), то модульные тесты указывают на то, что некоторые переосмысления и возможный повторный факторинг могут быть в порядке. Отделите понятия интерфейса от класса, и тестирование станет более очевидным. (Кстати, это положительный результат теста ... определение информации о классе, который может потребоваться изменить). Однако, чтобы ответить, да, нет ничего, что можно было бы проверить относительно частного участника. Только публичные функции. – David

2

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

Типичный тест вызовет конструктор, а затем вызовет общедоступное свойство или метод и проверит, что результат соответствует ожидаемому. Тестирование таким образом означает, что если вы позже измените свою реализацию (например), лениво постройте BudgetProvider только тогда, когда это необходимо, все ваши тесты все равно будут работать. Детали реализации, например, когда частный член является или не является нулевым, не имеют отношения к клиентам вашего класса, и поэтому нет необходимости тестировать его в своих модульных тестах.

+0

Я думаю, что вы имеете в виду модульные тесты, должны * не проверять личные данные, нет? если так, согласился. – Paul

+0

@Paul: Да, спасибо! Это действительно то, что я хотел написать. –

1

Если вы используете mestest, щелкните правой кнопкой мыши исходный класс и нажмите кнопку create test accessor, выберите свой тестовый проект. Затем проверьте это условие, используя accessor (должен появиться в intellisense).

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

1

Вы не должны проверять какие-либо частные переменные ваших классов.

Почему вы хотите протестировать сам конструктор? Было бы целесообразно протестировать его, если есть логика. Например, вы создаете объект только в том случае, если заданные параметры верны, и вы выполняете проверку перед созданием объекта. В противном случае создайте объект и убедитесь, что он ведет себя так, как ожидалось. Предположительно, если конструктор работает неправильно, поведение объекта будет неверным.

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

+0

Хорошо спасибо и в случае установки значения (параметра конструктора) в private budget_provider в этом конструкторе, я высмеиваю budget_provider, чтобы проверить, вызван ли набор в budget_provider? – bAN

+0

Да. Это очень хороший подход - вы проверяете взаимодействия своего класса с его зависимостями (budget_provider). Вы можете проверить, происходит ли ожидаемое взаимодействие в зависимости от состояния объекта. – mfloryan

0

Другие ребята упомянули, что вам не следует делать при использовании модульного тестирования.

Я постараюсь найти способ сделать то, что вы хотите (вы все еще нужно проверить свой конструктор):

public BUDGET_MANAGER() 
{ 
    try 
    { 
     this.budget_provider = new BUDGET_PROVIDER(); 
    } 
    catch {} 

    if (this.budget_provider == null) 
     throw new NullReferenceException("Budget provider is null !"); 
} 
+0

Не обижайтесь, но это смешно. Если CLR не поврежден, «новый» не может вернуть значение null. Пример: напишите мне тест, демонстрирующий это исключение. – bryanbcook

+0

Вы должны рассматривать блоки кода как «псевдокод» по умолчанию. Как вы видите, исходный вопрос также имеет ту же проблему, но мы предполагаем, что он проинформировал это дело о читаемости. Я добавил «try/catch» над ключевым словом 'new', если он вас радует. – Xaqron

Смежные вопросы