XUnit - архитектура проектирования для размещения многократно используемых помощников по тестированию во внешней разделяемой библиотеке классов с помощью расширенных методов - PullRequest
0 голосов
/ 24 августа 2018

Разработка некоторых тестов XUnit для очень большого числа классов бизнес-объектов (более 400). Будет много повторяющегося кода, поэтому, используя принципы DRY, у нас есть несколько вариантов, как абстрагировать и инкапсулировать код в разделяемые библиотеки классов.

  1. Традиционный статический вспомогательный класс. Метод для общих тестов, передачи параметров для экземпляра и любых настроек.
  2. Методы расширения на бизнес-класс. Как и выше, но как метод расширения для самого бизнес-класса / типа интерфейса.

Создание тестов в качестве расширенных методов (вариант 2), нарушает ли это принятый принцип модульного тестирования, который предполагает тестирование только небольшого конкретного модуля. Как теперь цепочки небольших тестов можно сгруппировать в родительский тест?

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

Код ниже демонстрирует два варианта. Обратите внимание, что классы Helper будут находиться в другом проекте Class Lib, отдельном от проекта класса UnitTest (Test_Person).

using Xunit;
namespace CCTools.UnitTest.Main.XUnit.UnitTestPatterns
{

public class Test_Person
{
    /// <summary>
    ///     Use Extension methods, quick to code and easy to read.
    /// </summary>
    [Fact]
    public static void Test_Stuff_UseExtenions_A()
    {
        Person p = new Person();
        //Do lots of other config and tests...
        p.Test_IncreaseCreditRating(187);
        p.IsManager = true;
        p.Test_CreditRating_is_valid_for_manager();
    }

    [Fact]
    public static void Test_Stuff_UseExtenions_B()
    {
        Person p = new Person();
        //Do lots of other config and tests...

        p.Test_IncreaseCreditRating(59);
        p.Test_CreditRating_is_valid_for_manager();
    }

    /// <summary>
    ///     Use traditional Helper methods, not as easy to read or code.
    /// </summary>
    [Fact]
    public static void Test_Stuff_UseHelper_A()
    {
        Person p = new Person();
        //Do lots of other config and tests...

        PersonUniTestHelper.Test_IncreaseCreditRating(p, 10);
        p.IsManager = true;
        PersonUniTestHelper.Test_CreditRating_is_valid_for_manager(p);
    }
}
/// <summary>
///     Extension methods, which makes coding far easier on the eye and one is able to locate all methods
///     using intellisense at a glance.
/// </summary>
public static class PersonUniTestExtensionMethods
{
    public static void Test_IncreaseCreditRating(this Person person, int creditRating)
    {
        person.IncreaseCreditRating(creditRating);
        if (creditRating >= 100) Assert.Equal(100 * 1000, person.CreditLimit);
        else Assert.Equal(creditRating * 1000, person.CreditLimit);
    }

    public static void Test_CreditRating_is_valid_for_manager(this Person person)
    {
        if (person.IsManager) Assert.True(person.CreditRating >= 50);
    }
}

/// <summary>
///     Traditional static class for helpers
/// </summary>
public static class PersonUniTestHelper
{
    public static void Test_IncreaseCreditRating(Person person, int creditRating)
    {
        person.IncreaseCreditRating(creditRating);
        if (creditRating >= 100) Assert.Equal(100 * 1000, person.CreditLimit);
        else Assert.Equal(creditRating * 1000, person.CreditLimit);
    }

    public static void Test_CreditRating_is_valid_for_manager(Person person)
    {
        if (person.IsManager) Assert.True(person.CreditRating >= 50);
    }
}


public class Person
{
    public string FirstName { get; set; }
    public int CreditLimit { get; private set; }
    public int CreditRating { get; private set; }

    public bool IsManager { get; set; }

    /// <summary>
    ///     Simple action to set CreditLimit based on Rating.
    /// </summary>
    public void IncreaseCreditRating(int creditRating)
    {
        CreditRating = creditRating;
        CreditLimit = creditRating >= 100 ? 100 * 1000 : creditRating * 1000;
    }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...