Дизайн кода / Тестируемость Как? - PullRequest
2 голосов
/ 22 августа 2009

Моя команда разрабатывает библиотеку, которая обрабатывает вызовы в Active Directory для поиска и возврата списка людей.

У нас есть класс, в котором собрана информация о найденном человеке. Затем мы используем список, чтобы обернуть их. Когда мы вызываем поиск, он использует внутреннюю библиотеку System.Directory и возвращает объект SearchResultCollection. Затем мы перебираем его, чтобы создать список <> и вернуть его.

Мы разработали для класса person только свойства read (get), поскольку мы не хотим, чтобы вызываемый объект изменял информацию о person. Мы передаем объект SearchResult из библиотеки System.Directory на конструктор человека.

Моя проблема в том, что мы не можем это легко проверить.

До сих пор мои мысли были:

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

    К сожалению, это приведет к очень длинному списку параметров конструктора .... Пахнет для меня плохо.

  2. Разрешить классу персонажа иметь сеттеры для свойств.

    Опять же, плохо пахнет для меня, так как мы не можем контролировать вызываемого абонента с помощью этого.

  3. Рефакторинг:

    Я посмотрел на выдержку для интерфейса и адаптации методов параметров. Кажется, параметр Adapt имеет наибольшее обещание? Параметр Adapt кажется хорошим, потому что он помогает сломать зависимость, которую я имею от объекта SearchResult библиотеки каталогов. Так что, если в будущем я захочу сделать какой-нибудь другой поиск, мы в хорошей форме. По крайней мере, я так думаю?

  4. Подкласс объекта person и создание теста Person с установщиками ....

    Кажется, это будет работать, но не уверен, что это правильный путь?

  5. Насмешься

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

РЕДАКТИРОВАТЬ: Если насмешка - лучшая идея, пожалуйста, дайте мне знать ... Тем не менее, мне было бы интересно узнать, как это можно сделать без насмешек (или, возможно, это действительно не обходится без насмешек) ....

Буду признателен за руководство по этому вопросу.

Вот фрагмент кода:

    public class PeopleSearcher
{
   .... declarations left out....

    public List<Person> FindPerson(string FirstName, string LastName, string Login)
    {
         ...filter setup left out for brevity....

         _peopleFound = _directoryToSearch.FindAll();
        //Convert to list of persons....
            int cnt = 0;
            _listOfPeople = new List<Person>();
            while (cnt < _peopleFound.Count)
            {
                Person p = new Person(_peopleFound[0]);
                _listOfPeople.Add(p);
                cnt++;
            }
            return _listOfPeople;
        }

    }

    public class Person
    {
        private string sn;
        ....further declarations left out for brevity....

        public Person(SearchResult PersonFound)
        {
            sn = PersonFound.Properties["sn"].Count == 0 ? string.Empty : PersonFound.Properties["sn"][0].ToString();
            givenName = PersonFound.Properties["givenName"].Count == 0 ? string.Empty : PersonFound.Properties["givenName"][0].ToString();
            sAMAccountName = PersonFound.Properties["sAMAccountName"].Count == 0 ? string.Empty : PersonFound.Properties["sAMAccountName"][0].ToString();
            adsPath = PersonFound.Path == null ? string.Empty : PersonFound.Path;

        }

        public string LastName
        {
            get
            {
                return sn;
            }
        }

        .... more getters...
     }
}

Ответы [ 3 ]

1 голос
/ 23 августа 2009

«Насмешка» - это слово, которое обычно используется для всех типов двойных тестов . И в большинстве случаев люди или не "насмехаются", они притворяются или окурки. В любом случае, ваш 4-й вариант (подкласс и методы добавления) звучит для меня как самый простой способ, учитывая вашу базу кода, если вы хотите, чтобы объекты Person передавали другие методы. Потому что я не думаю, что вы говорите о проверке того, что объект person получает корректные свойства, установленные конструктором, верно?

0 голосов
/ 23 августа 2009

В своем макете (по фреймворку или иным образом) вам все равно придется в конечном итоге создавать объекты Person со значениями, что возвращает вас к исходной проблеме.

К счастью, есть два отличных решения:

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

2) Используйте класс Builder (как Джошуа Блох описывает в Effective Java). Вы должны создать открытый статический класс PersonBuilder внутри Person, который будет экспортировать метод построения и цепные спецификаторы параметров (например, сеттеры, но не вызываемые отдельно):

public class Person ....
   public static class PersonBuilder {
      public PersonBuilder (String firstName, String lastName) {...} // my sample has two required values
      public Person build() { ... }
      public PersonBuilder ssn (String value) { ... }
      public PersonBuilder adsPath (String value) { ... }
      ...
   }
   ...
}

Спецификаторы цепочечных значений выглядят так:

      public PersonBuilder ssn (String value) { 
         this.sn = value;
         return this;
      }

Тогда вызов для создания Персоны выглядит так:

   Person thisPerson = new Person.PersonBuilder ("John", "Smith").ssn("123-45-6789").adsPath("whatever");

Этот метод полностью скрывает методы, которые могут устанавливать значения (на самом деле у вас нет «установщиков»), но не позволяет вам иметь дело с длинными списками аргументов конструктора (что облегчает работу с необязательными значениями).

Кстати, вы также, вероятно, хотите сделать конструктор Person личным.

0 голосов
/ 22 августа 2009

Насмешься. Это та ситуация, для которой было придумано издевательство. Я только издевался над Ruby, так что я не уверен в состоянии дел для .net, но он должен хорошо работать.

При издевательстве вы можете осознать некоторые области, которые должны быть переработаны. Это тоже хороший план.

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