Поделиться через


Модульные тесты для универсальных методов

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

Аргументы типа и ограничения типов

При создании модульных тестов для универсального класса в Visual Studio, например для класса MyList<T>, создается два метода: универсальный вспомогательный метод и тестовый метод. Если класс MyList<T> имеет одно или несколько ограничений типа, аргумент типа должен соответствовать всем ограничениям типа. Чтобы убедиться, что универсальный код при тестировании работает должным образом при всех допустимых входных данных, тестовый метод вызывает универсальный вспомогательный метод со всеми ограничениями, которые нужно протестировать.

Примеры

В следующих примерах показаны модульные тесты для универсальных объектов.

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

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

Пример 1. Измерение автоматически созданного кода теста.

В этом разделе тестовый код тестирует метод SizeOfLinkedList(). Этот метод возвращает целочисленное значение, указывающее число узлов в связанном списке.

В первом примере кода, в разделе "Автоматически созданный код теста", показан неизмененный код, созданный в Visual Studio Premium или Visual Studio Ultimate. Во втором примере, в разделе "Измененный код теста", показано, как изменить код для тестирования метода izeOfLinkedList для двух типов данных, int и char.

Этот код иллюстрирует два метода.

  • Вспомогательный тестовый метод SizeOfLinkedListTestHelper<T>(). По умолчанию имя вспомогательного тестового метода содержит строку "TestHelper".

  • Тестовый метод SizeOfLinkedListTest(). Любой метод, помеченный атрибутом "TestMethod".

Автоматически созданный код теста

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

public void SizeOfLinkedListTestHelper<T>()
{
    T val = default(T); // TODO: Initialize to an appropriate value
    MyLinkedList<T> target = new MyLinkedList<T>(val); // TODO: Initialize to an appropriate value
    int expected = 0; // TODO: Initialize to an appropriate value
    int actual;
    actual = target.SizeOfLinkedList();
    Assert.AreEqual(expected, actual);
    Assert.Inconclusive("Verify the correctness of this test method.");
}

[TestMethod()]
public void SizeOfLinkedListTest()
{
   SizeOfLinkedListTestHelper<GenericParameterHelper>();
}

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

Измененный код теста

В следующем коде тестовый метод и вспомогательный тестовый метод были изменены для успешного тестирования метода SizeOfLinkedList().

Вспомогательный тестовый метод

Вспомогательный тестовый метод выполняет следующие действия, соответствующие строкам кода, перечисленным с шага 1 по шаг 5.

  1. Создание универсального связанного списка.

  2. Добавление четырех узлов в список. Тип данных содержимого этих узлов неизвестен.

  3. Присвоение предполагаемого размера списка переменной expected.

  4. Вычисление фактического списка и присвоение его переменной actual.

  5. Сравнение actual с expected с помощью оператора Assert. Если фактический размер не равен предполагаемому, тест не пройден.

Тестовый метод

Тестовый метод компилируется в код, который вызывается при запуске теста SizeOfLinkedListTest. Выполняются следующие действия, соответствующие строкам кода, на шагах 6 и 7.

  1. Укажите <int> при вызове вспомогательного тестового метода, чтобы проверить, что тест работает для переменных integer.

  2. Укажите <char> при вызове вспомогательного тестового метода, чтобы проверить, что тест работает для переменных char.

public void SizeOfLinkedListTestHelper<T>()
{
    T val = default(T); 
    MyLinkedList<T> target = new MyLinkedList<T>(val); // step 1
    for (int i = 0; i < 4; i++) // step 2
    {
        MyLinkedList<T> newNode = new MyLinkedList<T>(val);
        target.Append(newNode);
    }
    int expected = 5; // step 3
    int actual;
    actual = target.SizeOfLinkedList(); // step 4
    Assert.AreEqual(expected, actual); // step 5
}

[TestMethod()]
public void SizeOfLinkedListTest() 
{
    SizeOfLinkedListTestHelper<int>();  // step 6
    SizeOfLinkedListTestHelper<char>(); // step 7
}

Примечание

При каждом запуске SizeOfLinkedListTest метод TestHelper вызывается дважды.Оператор Assert должен в обоих случаях принимать значение "True", чтобы тест был пройден.В случае неудачи теста может быть неясно, чем она вызвана: вызовом, указавшим <int>, или вызовом, указавшим <char>.Чтобы узнать ответ, можно проверить стек вызовов или установить точки останова в тестовом метода и затем выполнить отладку при запуске теста.Дополнительные сведения см. в разделе Практическое руководство. Отладка во время выполнения теста в решении ASP.NET.

Пример 2. Использование ограничения типа.

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

Во втором разделе показан код тестового проекта.

Тестируемый проект

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace ClassLibrary2
{
    public class Employee
    {
        public Employee(string s, int i)
        {
        }
    }

    public class GenericList<T> where T : Employee
    {
        private class Node
        {
            private T data;
            public T Data
            {
                get { return data; }
                set { data = value; }
            }
        }
    }
}

Тестовый проект

Как и в случае с только что созданными модульными тестами нужно добавить окончательные операторы Assert в этот модульный тест, чтобы получить нужные результаты. Их следует добавлять не в метод с атрибутом TestMethod, а в метод "TestHelper", который в данном случае называется DataTestHelper<T>().

В данном примере параметр универсального типа T имеет ограничение where T : Employee. Это ограничение в тестовом методе не удовлетворяется. Следовательно, метод DataTest() содержит оператор Assert, который сообщает о необходимости указать ограничение типа для T. Сообщение этого оператора Assert выглядит так: ("No appropriate type parameter is found to satisfies the type constraint(s) of T. " + "Please call DataTestHelper<T>() with appropriate type parameters.");

Другими словами, при вызове метода DataTestHelper<T>() из тестового метода DataTest() нужно передать параметр типа Employee или класс, производный от Employee.

using ClassLibrary2;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestProject1

{
    [TestClass()]
    public class GenericList_NodeTest
    {
    
        public void DataTestHelper<T>()
            where T : Employee
        {
            GenericList_Shadow<T>.Node target = new GenericList_Shadow<T>.Node(); // TODO: Initialize to an appropriate value
            T expected = default(T); // TODO: Initialize to an appropriate value
            T actual;
            target.Data = expected;
            actual = target.Data;
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        [TestMethod()]
        public void DataTest()
        {
            Assert.Inconclusive("No appropriate type parameter is found to satisfies the type constraint(s) of T. " +
            "Please call DataTestHelper<T>() with appropriate type parameters.");
        }
    }
}

См. также

Основные понятия

Составляющие модульного теста

Проверка кода при помощи модульных тестов