Подход модульного теста для универсальных классов/методов

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

Например (относящийся к моему примеру кода ниже). Это был бы случай, имеют 2 или 3 раза тесты для покрытия тестирования методов несколькими различными типами TKey, классов TNode? Или всего один класс достаточно?

public class TopologyBase<TKey, TNode, TRelationship> 
    where TNode : NodeBase<TKey>, new() 
    where TRelationship : RelationshipBase<TKey>, new()

{
    // Properties
    public Dictionary<TKey, NodeBase<TKey>> Nodes { get; private set; }
    public List<RelationshipBase<TKey>> Relationships { get; private set; }

    // Constructors
    protected TopologyBase()
    {
        Nodes = new Dictionary<TKey, NodeBase<TKey>>();
        Relationships = new List<RelationshipBase<TKey>>();
    }

    // Methods
    public TNode CreateNode(TKey key)
    {
        var node = new TNode {Key = key};
        Nodes.Add(node.Key, node);
        return node;
    }

    public void CreateRelationship(NodeBase<TKey> parent, NodeBase<TKey> child) {
    .
    .
    .
11
задан Greg 12 May 2010 в 11:02
поделиться

5 ответов

Обычно я создаю DummyClass для тестирования, чтобы передать его в качестве общего аргумента (в вашем случае вы должны создать 3 класса), а затем тестирую класс (TopologyBase) один раз.

Тестирование с разными родовыми типами не имеет смысла, так как родовой тип не должен ломать класс ToopologyBase.

3
ответ дан 3 December 2019 в 11:03
поделиться

Вы можете использовать фреймворк для проверки ожидаемого взаимодействия между вашим классом и универсальным типом. Для этого я использую Rhino Mocks .

1
ответ дан 3 December 2019 в 11:03
поделиться

Это действительно может зависеть от вашего кода, но есть как минимум две вещи для размышлений:

  • Private / Public: Если ваша реализация использует или может когда-нибудь использовать отражение или DLR (напрямую или через ключевое слово dynamic в C #) для некоторых операций, вам следует протестировать хотя бы один тип, который не виден из исполняющая сборка.
  • ValueType / ReferenceType: в некоторых случаях может потребоваться проверка разницы между ними, например
    • Вызов метода Object для типов значений, таких как ToString или Equals, всегда является правильным, но не со ссылками, поскольку они могут иметь значение NULL.
    • Если вы проводите тестирование производительности, передача типов значений может иметь последствия, особенно если они большие (этого не должно происходить, но между рекомендациями и реальностью иногда есть небольшой разрыв ...)
2
ответ дан 3 December 2019 в 11:03
поделиться

Многое зависит от ваших общих ограничений. Если для одного или нескольких параметров типа требуется ограничение интерфейса или базового класса, теперь существует зависимость от контракта интерфейса. Поскольку логика вашего класса может частично зависеть от поведения класса, реализующего интерфейс, вам может потребоваться имитировать интерфейс различными способами, чтобы реализовать все ваши логические пути. Например, если у вас есть T: IEquatable , вам нужно будет использовать тип со значимым поведением равенства, например int.

0
ответ дан 3 December 2019 в 11:03
поделиться

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

public class TestingTopologyBase : TopologyBase<KeyType, NodeType, RelationshipType> ...

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

Эти реализации Testing [ProductionType] часто являются отличным местом для кода модульного тестирования, чтобы определить, что на самом деле делает тестируемый универсальный тип. Например, вы можете хранить информацию, которая позже может быть использована вашим кодом модульного теста для проверки того, что происходило во время теста.

Затем в методах модульного тестирования создайте экземпляры класса TestingTopologyBase. Таким образом, вы тестируете универсальный тип изолированно от любых производственных типов, производных от него.

Пример:

[TestClass]
public class TopologyBaseFixture {

    [TestMethod]
    public void SomeTestMethod() {
       var foo = new TestingTopologyBase(...);
       ...test foo here
1
ответ дан 3 December 2019 в 11:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: