Как проверить несколько объектов одного типа в NUnit - PullRequest
0 голосов
/ 03 января 2019

Я сейчас пытаюсь выучить NUnit в первый раз.

Для программы на C #, которую я хочу разрабатывать с использованием TDD, я решил, что хочу написать класс User для начала.Этот User класс будет (семантически) выглядеть следующим образом:

using System;

namespace SSH_file_drop
{
    public class User
    {
        private Boolean authenticated = false;

        public string userName = null;

        //one-time object 'transmission' instance to allow single-use file transmission field
        Transmission fileVehicle = null;

        //property to discern whether user has been correctly authenticated
        public Boolean isAuthenticated 
        {
            get;
        }

        public Boolean canSend ()
        {
            if (authenticated)
            {
                return this.userType != "sender";
            }
            return false;
        }

        public User(String inputUName)
        {
            String userName = inputUName;
        }

        public static void generateUser(string userName)
        {
            //contact server to attempt to register new user
        }

        public void ChangePassword(String oldPassword, String newPassword)
        {
            //ask server to change user password
        }

        public Boolean SetUpTransmission()
        {
            if (canSend())
            {
                try
                {
                    fileVehicle = new Transmission(this);
                    return true;
                }
                catch (e)
                {
                    //write exception message
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
    }
}

На самом деле просто код-заполнитель на данный момент.

Чтобы протестировать класс User, я пытаюсьнаписать TestFixture, которая создает отдельные экземпляры класса User и каким-то образом сохраняет их до тех пор, пока они не будут разобраны, проводя одинаковые тесты для каждого объекта.

Моя идея заключалась в создании массива объектов User в качестве данных TestCaseисточник, чтобы проверить все по порядку с помощью атрибута [Order(<n>)] (bar метод тестирования инициализации экземпляра пользователя), но я прочитал здесь , что новый экземпляр TestFixture будет создан для каждого метода в нем во время выполнения,поэтому я не смог бы изменить постоянные данные в тестовом приборе таким образом.

Поскольку я пытаюсь реализовать логику с отслеживанием состояния - User object isAuthenticated () (и эта аутентификация зависит от последующих тестов после этого, поскольку все пользовательские данные моделируются как хранящиеся в удаленной базе данных), есть лиспособ продолжить без создания тестов с повторяющимися операциями (создание объекта, аутентификация, проверка userType и т. д.) и, таким образом, несколько утверждений?

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Отвечая на ту часть вашего вопроса, которая касается работы NUnit ...

Ответ, который вы процитировали относительно времени жизни экземпляров приборов в NUnit, вводит в заблуждение и немного удивляет, потому что в этом нет большой загадки!

Цитата из Джима Ньюкирка, основной разработки NUnit V2, является просто заявлением о том, как он хотел, чтобы он сделал NUnit V2. Он реализовал эти идеи в рамках xUnit.net, но это не относится к NUnit 3.

NUnit 3, как и NUnit V2, создает один экземпляр TestFixture, который используется для всех ваших тестов. Вы можете создавать объекты для использования в своих тестах, используя [OneTimeSetUp], и сохранять их как члены класса. Если эти объекты с состоянием, следует избегать использования параллельного выполнения тестов для тестов в приборе, который их использует.

Если требуется дополнительная настройка для каждого теста, вы можете использовать [SetUp] для этой цели и [TearDown], чтобы удалить любые изменения, которые могут негативно повлиять на последующие тесты.

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

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

Обязательно ознакомьтесь с подробностями всего вышеперечисленного в документации: https://github.com/nunit/docs/wiki

0 голосов
/ 03 января 2019

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

Это подход, который вы упомянули, за исключением немного другого подхода.

Другие проблемы, которые следует рассмотреть с вашим предложенным подходом, которого я бы предложил избежать, это упорядоченное и / или параллельное выполнение тестов: если у вас есть ряд объектов с состоянием, тесты не смогутНадежно работать параллельно или не по порядку.

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

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

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

private bool m_IsAuthenticated;

public bool IsAuthenticated {
  get {
    return m_IsAuthenticated;
  }
}

public void Set_IsAuthenticated_ForTestONLY(bool value) {
  m_IsAuthenticated = value;
}
...