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



каков наилучший способ модульного тестирования метода, который ничего не возвращает? В частности, в c#.



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

441   11  

11 ответов:

если метод ничего не возвращает, это либо один из следующих

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

императивные методы-вы можете проверить если задача действительно была выполнена. Проверьте, действительно ли произошло изменение состояния. например,

void DeductFromBalance( dAmount ) 

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

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

void OnAccountDebit( dAmount )  // emails account holder with info

могут быть проверены проверка, если письмо отправляется

разместить более подробную информацию о вашем фактическом методе и люди смогут ответить лучше.
обновление: ваш метод делает 2 вещи. Я бы разбить его на два метода, которые теперь могут быть независимо проверены.

string[] ExamineLogFileForX( string sFileName );
void InsertStringsIntoDatabase( string[] );

String[] можно легко проверить, предоставив первый метод с фиктивным файлом и ожидаемыми строками. Второй-немного сложнее.. вы можете либо использовать макет (google или поиск stackoverflow на издевательских фреймворках), чтобы имитировать БД или ударить по фактической БД и проверить, были ли строки вставлены в нужное место. Проверьте этой теме для некоторых хороших книг... Я бы рекомендовал прагматичное модульное тестирование, если вы находитесь в кризисе.
В коде он будет использоваться как

InsertStringsIntoDatabase( ExamineLogFileForX( "c:\OMG.log" ) );

проверьте его побочные эффекты. Это включает в себя:

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

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

Как всегда: проверьте, что должен делать метод!

должен ли он изменить глобальное состояние (uuh, запах кода!) куда-нибудь?

должен ли он вызывать интерфейс?

должен ли он вызывать исключение при вызове с неправильными параметрами?

должен ли он не создавать исключений при вызове с правильными параметрами?

Он должен ...?

Void возвращаемые типы / подпрограммы-это старые новости. Я не сделал тип возврата Void (если только я не был очень ленив) примерно за 8 лет (со времени этого ответа, так что немного раньше, чем был задан этот вопрос).

вместо метода типа:

public void SendEmailToCustomer()

сделайте метод, который следует за int от Microsoft.Метод tryparse() парадигма:

public bool TrySendEmailToCustomer()

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

кроме того, bool не является единственным типом состояния. Существует несколько случаев, когда ранее выполненная подпрограмма может фактически возвращать три или более различных состояния (хорошее, нормальное, плохое и т. д.). В этих случаях вы просто используете

public StateEnum TrySendEmailToCustomer()

однако, хотя парадигма Try-Paradigm несколько отвечает на этот вопрос о том, как проверить возврат пустоты, есть и другие соображения. Например, во время / после цикла TDD, вы бы "рефакторинг" и заметили, что вы делаете две вещи с вашим методом... тем самым нарушается принцип "единой ответственности".- Так что об этом надо позаботиться в первую очередь. Во-вторых, вы могли идентифицировать зависимость... вы касаетесь "постоянных" данных.

если вы выполняете доступ к данным в рассматриваемом методе, вам нужно рефакторинг в архитектуру n-уровня или N-уровня. Но мы можем предположить, что когда вы говорите " строки затем вставляются в базу данных", вы на самом деле имеете в виду, что вы называете уровень бизнес-логики или что-то в этом роде. Да, мы это предположим.

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

public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)

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

Итак, в вашем живом коде вы переходите в реальный

Это будет иметь некоторое влияние на объект.... запрос на результат эффекта. Если он не имеет никакого видимого эффекта его не стоит модульного тестирования!

предположительно метод делает что-то, а не просто возвращается?

Если это так, то:

  1. если он изменяет состояние его владельца объекта, то вы должны проверить, что состояние изменилось правильно.
  2. если он принимает какой-то объект в качестве параметра и изменяет этот объект, то ваш должен проверить, что объект правильно изменен.
  3. если он выдает исключения в определенных случаях, проверьте, что эти исключения правильно заброшенный.
  4. если его поведение зависит от состояния его собственного объекта или какого-либо другого объекта, установите состояние и проверьте, что метод имеет правильный Ithrough один из трех методов тестирования выше).

Если вы сообщите нам, что делает этот метод, я мог бы быть более конкретным.

попробуйте это:

[TestMethod]
public void TestSomething()
{
    try
    {
        YourMethodCall();
        Assert.IsTrue(true);
    }
    catch {
        Assert.IsTrue(false);
    }
}

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

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

какой бы экземпляр вы ни использовали для вызова метода void, вы можете просто использовать,Verfiy

Например:

в моем случае его _Log экземпляр и LogMessage Это метод, который будет проверен:

try
{
    this._log.Verify(x => x.LogMessage(Logger.WillisLogLevel.Info, Logger.WillisLogger.Usage, "Created the Student with name as"), "Failure");
}
Catch 
{
    Assert.IsFalse(ex is Moq.MockException);
}

- Это Verify выбрасывает исключение из-за сбоя метода тест не будет выполнен ?

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

Comments

    Ничего не найдено.