Как создать правильный модульный тест для метода, который возвращает список?

у меня есть этот метод:

public DataSourceResult GetProjectBySpec(int projectId, int seasonId, int episodeId)
        {
            using (var rep = RepositoryHelper.GetTake2Repository<ITake2RepositoryBase>())
            {
                var spec = new ProjectCrewsByProjectSpec(projectId, seasonId, episodeId);

                var personList = rep.GetList<ProjectDGACrew>(spec).Select(p => new
                {
                    //big query...
                    .ToDataSourceResult();

                return personList;
            }
        }

мне нужно создать модульный тест для этого.

первый вопрос:

  1. для чего я тестирую? Я только проверяю, возвращает ли метод список?

  2. Если да, то как я могу это проверить?

это то, что у меня есть до сих пор:

    [TestClass]
    public class CrewControllerTest
    {
        [TestMethod]
        public void GetProjectCrewsBySpecTest()
        {
            // arrange
            int projectId = 1;
            int seasonId = 2;
            int episodeId = 3;

            // act
            var crewController = new CrewController();
            DataSourceResult dsr = crewController.GetProjectCrewsBySpec(1, 2, 3);

            // assert
            // what or how do I assert here? Am I just checking whether "dsr" is a list? How do I do that?
        }
    }

4 ответов


Я тоже не эксперт, и я только делал TDD некоторое время, поэтому возьмите то, что я пишу в этом бессвязном ответе с ложкой соли :) я уверен, что кто-то еще может указать, если я сделал какие-то действительно плохие ошибки или указал вам в неправильном направлении...

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

  • RepositoryHelper.GetTake2Repository()) бросать? (Depencency issue)
  • бросание конструктора ProjectCrewsByProjectSpec? (Проблема зависимости)
  • rep.GetList (spec) бросание? кендо (это кендо,верно?) (Проблема зависимости)
  • ToDataSourceResult() бросать? (Поведенческий вопрос)

модульное тестирование - это тестирование вещей в полной изоляции от их зависимостей, поэтому на данный момент я бы сказал, что это больше похоже интеграционный тест, в котором вы действительно не заботятся как системы взаимодействуют, вы просто хотите убедиться, что для данного projectID, seasonId и episodeId вы получите ожидаемые результаты - в этом случае каковы действительно тестирование респ.Метод getlist() метод в сочетании с .ToDataSourceResult


модульные тесты обычно (должны) тестировать контракт, как это понимает клиент класса. Когда клиент вашего кода вызывает .GetProjectBySpec(1, 2, 3), чего он ожидает? Модульный тест должен ответ такой вопрос:

когда в репозитории есть 5 проектов (A, B, C, D, E) и я называю GetProjectBySpec с параметрами 1, 2, 3, Я должен получить проекты B и C

в вашем случае это может зависеть от того, что делается в //big query... часть. Если это фильтрации/преобразования из результатов, возвращенных из репозитория, это то,что вы должны проверить.

обратите внимание, что вам, вероятно, придется изменить несколько вещей, чтобы сделать этот тест изолированным (из репозитория / базы данных):

  • RepositoryHelper.GetTake2Repository должно быть обернуто в интерфейс, вводят как зависимость и глумились позже в модульном тесте
  • если new ProjectCrewsByProjectSpec создает сложный объект, вы можете использовать завод вместо

когда у вас будет издеваться репозиторий, вы просто проинструктируете свой макет вернуть некоторый заранее известный список элементов, когда он вызывается с помощью matching


Я пишу тесты таким образом:

  1. напишите тест для каждого пути через код.
  2. напишите тест для граничных условий. Например: ноль, один или два элемента в списке. Плохие параметры, etc.
  3. пишут отрицательные тесты. Это труднее, так как вы можете написать бесконечное количество бесполезных анализов. Хорошим примером является проверка того, что вещи, которые не следует изменять, не меняются.

удачи


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

[TestClass]
    public class CrewControllerTest
    {
        [TestMethod]
        public void GetProjectCrewsBySpecTest()
        {
          // arrange
          const String ExpectedOutput = "";
          int projectId = 1;
          int seasonId = 2;
          int episodeId = 3;

          // act
          var crewController = new CrewController();
          var resultList= crewController.GetProjectCrewsBySpec(1, 2,3) as DataSourceResult;
          var someInsideData = resultlist.FirstOrDefault().GetType().GetProperty("PropertyName").GetValue(resultList.FirstOrDefault(),null);

          // assert
          Assert.AreEqual(someInsideData , ExpectedOutput);          
        }
}