Как я могу проверить, вызывается ли закрытый метод класса с помощью rhino mock? - PullRequest
0 голосов
/ 01 марта 2019

Я новичок в C #, а также издевается над носорогом.Я искал и нашел похожие темы с моим вопросом, но не смог найти правильного решения.

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

  public void calculateItems()
    {
        var result = new Result(fileName, ip, localPath, remotePath);

        calculateItems(result, nameOfString);
    }

    private void calculateItems(Result result, string nameOfString )

Как вы видите из приведенного выше кода, у меня есть два метода с абсолютно одинаковыми именами calcItems, но у общедоступного нет параметров, у частного - два параметра.Я пытаюсь понять, когда я вызываю public один в моем unittest, вызывается закрытый метод?

    private CalculateClass sut;
    private Result result; 

    [SetUp]
    public void Setup()
    {
      result = MockRepository.GenerateStub<Result>();
      sut = new CalculateClass();
    }

    [TearDown]
    public void TearDown()
    {

    }

    [Test]
    public void test()
    {     
        sut.Stub(stub => stub.calculateItems(Arg<Result>.Is.Anything, Arg<string>.Is.Anything));

        sut.calculateItems();

        sut.AssertWasCalled(stub => stub.calculateItems(Arg<Result>.Is.Anything, Arg<string>.Is.Anything));
    }

В моем unittest я принимаю такую ​​ошибку, которая гласит: «Нет метода перегрузки для convertItems, принимающего два аргумента».Есть ли способ проверить это без каких-либо изменений в исходном коде?

Ответы [ 3 ]

0 голосов
/ 01 марта 2019

Если ваш публичный метод вызывает ваш приватный, то в ваших тестах произойдет то же самое.Тесты - это не что иное, как код, который можно запускать и отлаживать, и вы можете попробовать это, чтобы посмотреть, что произойдет.

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

Теперь давайте обсудим, что вы на самом деле тестируете.

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

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

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

0 голосов
/ 01 марта 2019

Когда вы говорите, что вам нужно знать, вызваны ли ваши закрытые методы, это может иметь две разные интерпретации:

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

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

Что касается второй интерпретации: Если вы хотите понять, что происходит в коде, хороший подход - использовать отладчик и просто пройтись по коду, чтобы увидеть, какая функция вызывается.Поскольку я не являюсь экспертом в C #, я не могу рекомендовать какой-либо конкретный инструмент отладки, но найти некоторые рекомендации по этому поводу в Интернете не должно быть трудным.Этот подход будет отвечать вашим требованиям, не требуя изменений в исходном коде

Другая возможность, в частности, если вас интересует, покрывается ли ваши частные функции тестами, заключается в использовании инструмента покрытия тестов для C #.Инструмент покрытия покажет вам, был ли вызван закрытый метод или нет.Опять же, это не потребует внесения каких-либо изменений в исходный код.

Относительно первой интерпретации вашего вопроса: Если вы хотите проверить, что некоторая приватная функция вызывается как часть вашегокритерий успешности теста, предпочтительно делать это с тестами, которые используют публичный API.Затем в этих тестах вы сможете судить, вызывается ли закрытая функция из-за влияния частной функции на результат теста.

И, в отличие от других мнений, вы должны проверитьреализация.Основная цель юнит-тестирования - найти ошибки в коде.Разные реализации имеют разные ошибки.Вот почему люди также используют инструменты покрытия, чтобы увидеть, охватили ли они код своей реализации.И, охват недостаточен, вам также необходимо проверить граничные случаи выражений и т. Д. Конечно, наличие ремонтопригодных тестов и тестов, которые не ломаются без необходимости в случае рефакторингов, являются хорошими целями (почему тестирование через открытый API, как правило, хороший подход -но не всегда), но они являются второстепенными целями по сравнению с целью найти все ошибки.

0 голосов
/ 01 марта 2019

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

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

Таким образом, вы должны задать себе вопрос: каковы ожидаемые результаты при вызове этой операции?:

calculateItems()

Это ничего не возвращает, так что делает это делает?В каком состоянии он каким-то образом изменяется? Это - это то, что должен соблюдать ваш тест, а не детали реализации, а наблюдаемый результат.(И если операция не имеет наблюдаемого результата, то нет разницы между "пройден" или "не пройден", поэтому проверять нечего.)

Мы не можем видеть детали вашегокод, но возможно, что наблюдаемый результат полностью связан с другим компонентом.Если это так, то другой компонент является зависимостью для этой операции, и цель модульного теста состоит в том, чтобы смоделировать эту зависимость, чтобы операция могла быть протестирована независимо от зависимости.Затем может потребоваться изменить компонент, чтобы обеспечить зависимость, а не внутреннее управление.(Это называется принцип обращения зависимостей .)

Также обратите внимание ...

но я не могу изменить исходный код

Это отдельная проблема полностью.Если вы действительно не можете изменить исходный код, тогда ценность этих тестов резко снижается и, возможно, полностью исключается.Если тест не пройден, что вы можете с этим поделать?Ничего такого.Потому что вы не можете изменить код.Итак, что вы тестируете?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...