Как выполнить модульное тестирование строкового значения в классе объектов

Я пытаюсь сделать модульный тест для класса объекта, который содержит в нем значения с помощью get / sets.

Я понимаю, как вы можете проверить вычисление чисел.

Но как вы тестируете get / sets там, где нет таких методов, как x + y?

Это класс, который мне нужно протестировать:

public class Train
{
    //Variables to hold each Trains details. Using different data types for specific entrys when necessary.
    private string _trainID;
    private string _departure;
    private string _destination;
    private string _type;
    private string _interStop;
    private TimeSpan _departureTime;
    private string _departureDay;
    private bool _sleeperBerth;
    private bool _firstClass;

    //Get/Set for setting Train ID value.
    public string TrainID
    {
        get { return _trainID; }
        set { _trainID = value; }
    }

    //Get/Set for setting departure value.
    public string Departure
    {
        get { return _departure; }
        set { _departure = value; }
    }

    //Get/Set for setting destination value.
    public string Destination
    {
        get { return _destination; }
        set { _destination = value; }
    }

    //Get/Set for setting type value.
    public string Type
    {
        get { return _type; }
        set { _type = value; }
    }

    //Get/Set for setting Intermediate Stop value.
    public string IntermediateStop
    {
        get { return _interStop; }
        set { _interStop = value; }
    }

    //Get/Set for setting Departure Time value.
    public TimeSpan DepartureTime
    {
        get { return _departureTime; }
        set { _departureTime = value; }
    }

    //Get/Set for setting Departure Day value.
    public string DepartureDay
    {
        get { return _departureDay; }
        set { _departureDay = value; }
    }

    //Get/Set for setting  Sleeper Berth value.
    public bool SleeperBerth
    {
        get { return _sleeperBerth; }
        set { _sleeperBerth = value; }
    }

    //Get/Set for setting First Class value.
    public bool FirstClass
    {
                get { return _firstClass; }
        set { _firstClass = value; }
    }
}

Я также составил какой-то модульный тест, который я считаю правильным, но он просто не работает. Может ли кто-нибудь дать мне представление о том, как я бы это сделал?

Это тест, который я придумал (неужели он так прост и легок?):

namespace TrainTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestTrainID()
        {
            Train train = new Train();

            string id = "1S45";

            train.TrainID = "1S45";

            Assert.AreEqual(id, train.TrainID);
        }
    }
}

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

Sam W 07.12.2018 16:35

Не получается как? что такое сообщение об ошибке?

Nkosi 07.12.2018 16:49

@ESuth Есть новости о статусе этой проблемы?

Nkosi 12.12.2018 13:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
701
3

Ответы 3

Вы должны проверить поведение и состояние изменений, вызванных поведением. У вашего класса нет поведения, и его состояние не меняется из-за поведения. Тестировать не на чем.

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

Тогда неудачные тесты укажут на ошибку в вашем конструкторе.

Итак, предполагая, что у вашего класса есть конструктор вроде (упрощен только для демонстрационных целей)

public class Train {        
    private string _trainID;

    public Train(string id) {
        _trainID = id;
    }

    //Get/Set for setting Train ID value.
    public string TrainID {
        get {
            return _trainID;
        }
        set {
            _trainID = value;
        }
    }
}

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

public class TrainUnitTest
{
    [Fact]
    public void Should_Get_TrainID()
    {
        //arrange
        var expected = "1S45";
        var subject  = new Train("1S45");

        //act
        string actual = subject.TrainID;

        //assert
        Assert.Equal(expected, actual);
    }
}

Да, @Nkosi, но во всех примерах не упоминается конструктор!

sarvasana 08.12.2018 07:09

Это не проблема. Я обновил ваш пример, включив в него конструктор, чтобы OP лучше понимал, что вы объясняли.

Nkosi 08.12.2018 07:21

Ура, я ценю это!

sarvasana 08.12.2018 12:22

Вы зря тратите время на изобретение колеса.

Замените свои свойства на автоматически реализуемые свойства, и вдруг у вас не будет модульных тестов необходимость для ваших геттеров и сеттеров, потому что компилятор создает весь код геттера / сеттера и проверяет его правильность:

public class Train
{
    public string TrainID { get; set; }
    public string Departure { get; set; }
    ... etc. ...
}

(Поскольку вы упомянули, что это «игрушечный пример», предназначенный для начала работы с модульными тестами: да, предлагаемый вами тест подходит.)

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

sarvasana 07.12.2018 16:09

@Kris: Я не согласен: нет необходимости в модульном тестировании автоматических установщиков или получателей свойств. Разработчики Roslyn позаботились об этом модульным тестированием.

Heinzi 07.12.2018 16:10

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

sarvasana 07.12.2018 16:11

@Kris: Я полностью согласен с этим. Однако я не понимаю, насколько это противоречит моему ответу. Исходное состояние кода имел изменяется: средство установки TrainID изменило это состояние поля члена _trainID.

Heinzi 07.12.2018 16:12

С автоматически реализуемыми свойствами разницы нет. Их вспомогательные поля генерируются компилятором.

sarvasana 07.12.2018 16:13

@Kris: Совершенно верно. Разница в том, что код для этого не написан вручную OP (а автоматически написан компилятором) и, следовательно, не нуждается в тестировании (если вы доверяете компилятору, что я бы сделал).

Heinzi 07.12.2018 16:14

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

ESuth 07.12.2018 16:15

У меня есть отдельный модульный тест, который проверяет фактические математические вычисления. Но единственный способ, который я вижу, - это проверить get / set. Просто создать строку с определенным значением, а затем создать объект поезда с таким же значением в требуемом свойстве и проверить, что два значения равны

ESuth 07.12.2018 16:16

@ESuth Ваш профессор специально говорил вам не использовать автоматически реализуемые свойства?

Sam W 07.12.2018 16:17

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

Flater 07.12.2018 16:17

@Flater нет, я не такой.

sarvasana 07.12.2018 16:18

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

nos 07.12.2018 16:18

@Kris: Кроме того, если вы не собираетесь верить, что автоматические установщики работают, как задумано, как вы когда-нибудь собираетесь писать модульный тест, который не полагается на автоматические установщики? Потому что, если сеттер может ошибаться, может быть и геттер, а это значит, что вы никогда не сможете доверять автоматизированным свойствам, как бы тщательно вы их ни тестировали.

Flater 07.12.2018 16:19

@Flater: В защиту Криса, я думаю, он скорее защищает тривиальные ручные геттеры / сеттеры в игрушечном примере OP не нужно тестировать. Я не подписываюсь на это в целом (это код, в котором мог бы неисправен, шаблонный код особенно, который может быть скопирован / вставлен), но я вижу, что соотношение затрат и выгод модульного тестирования такого кода не очень хорошее и Я бы, наверное, не стал тестировать его сам.

Heinzi 07.12.2018 16:19

@Flater OP публикует класс, содержащий свойства с полями поддержки. ЕСЛИ существует конструктор, устанавливающий резервные поля, тогда да, правильно проверить, выставляют ли общедоступные свойства значения, установленные в поддерживающих полях.

sarvasana 07.12.2018 16:21

@ESuth: Если это игрушечный пример, я думаю, что предложенный вами модульный тест в порядке. Однако я не понимаю, почему это не удается. Не могли бы вы добавить сообщение об ошибке к вашему вопросу?

Heinzi 07.12.2018 16:39

@Flater: «Вы говорите, что необходимость писать модульные тесты волшебным образом исчезает при использовании автоматически реализуемых свойств, что неверно». Думаю, я понимаю, в чем заключается недоразумение. Я изменил свой ответ на * "... вдруг вам не нужны модульные тесты для ваших геттеров и сеттеров ...". Вы согласны сейчас?

Heinzi 07.12.2018 16:42

Помимо семантики синтаксиса, если не было фактической ошибки в коде, который не показан, как вы упомянули, это пример игрушки или опечатка со значениями, переданными в тест, которая вызывает ошибку caparison, предоставленный тест должен пройти, как написано

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

[TestClass]
public class TrainUnitTest
{
    [TestMethod]
    public void Should_Get_TrainID() {
        //Arrange
        string expected = "1S45";
        Train subject = new Train();
        subject.TrainID = expected;

        //Act
        string actual = subject.TrainID;

        //Assert
        Assert.AreEqual(expected, actual);
    }
}

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

Ссылка Основы модульного тестирования

Другие вопросы по теме