Использовать отражение или свойство при юнит-тестировании? - PullRequest
4 голосов
/ 08 июля 2010

Это класс, который меня немного беспокоит.Моя цель состоит в модульном тестировании списка адресов:

public class LabelPrinter
{
    private readonly IEnumerable<Address> _addresses;

    public LabelPrinter(IEnumerable<Address> addresses)
    {
        _addresses = addresses;
    }

    public Document Create()
    {
        // ... Generate PDF, etc ...
    }
}

Итак, что лучше:

  1. Используйте отражение для проверки частной собственности, или
  2. Так какоригинальный IEnumerable можно изменить извне, сделать публичный геттер и протестировать его?

Ответы [ 4 ]

7 голосов
/ 08 июля 2010

В общем, частные члены не должны подвергаться модульному тестированию, поскольку все, что класс делает со своими закрытыми членами, должно как-то отражаться на внешне тестируемом поведении объекта.Другими словами, кого волнует, что там происходит, если его внешнее поведение таково, каким оно должно быть.

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

Другими словами - если вам нужно протестировать класс Address, делайте это самостоятельномодульные тесты, а не из LabelPrinter тестов.Если вы должны использовать один из двух ваших методов, используйте второй, а не рефлексию.

1 голос
/ 08 июля 2010

Что вы пытаетесь проверить в списке addresses здесь? В приведенном выше примере кода ваша работа на самом деле довольно проста, поскольку вы можете внедрить список через конструктор. Таким образом, в ваших тестах вы можете получить доступ к списку как таковому и, следовательно, не обязательно выставлять его снова:

[Test]
public void Test()
{
    IEnumerable<Address> addresses = new List<Address>();
    LabelPrinter printer = new LabelPrinter(addresses);

    ... // execute your test here

    Assert.AreEqual(blah, addresses.get(0));
    // or any other assertion you want to make on the addresses list
    // created up above.
}
0 голосов
/ 08 июля 2010

Тест Create, а не сеттер (что эффективно здесь).Я считаю, что тестирование сеттеров / геттеров - пустая трата времени.Особеннотак как большую часть времени сеттер должен выполняться для выполнения какого-либо другого теста.Они также по большей части слишком просты, чтобы их потерпеть неудачу.

Поэтому вместо того, чтобы проверять, что LabelPrinter имеет _addresses, а это Y, проверьте, что выходные данные Create содержат соответствующие детали.

0 голосов
/ 08 июля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...