Какой простейший модульный тест для реализации того или иного метода называется? - PullRequest
1 голос
/ 02 сентября 2011

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

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

Что я должен изменить или реализовать (например, интерфейс и т. Д.), Чтобы я мог утверждать, что "метод MakeNoise вызывает метод Барка"

Я могу использовать RhinoMocks, если это необходимо.

public class Animal
{
    public string AnimalType {get; set;}
    public string Bark()
    {
        if(AnimalType=="dog")
        {
            return "Hof! Hof! Hof!";
        }

        return string.Empty;
    }

    public string MakeNoise()
    {
        if(AnimalType=="dog")
        {
            return Bark();
        }

        return 
            string.Empty;

    }
}

[TestMethod]
public void MakeNoise_WithAnimalTypeDog_CallsBarkMethod()
{

    var dog = new Animal(){AnimalType="dog"};
    dog.MakeNoise();

    // How can I test if the MakeNoise method called BarkMethod ?

}

Ответы [ 3 ]

3 голосов
/ 02 сентября 2011

Это то, что вас интересует, вывод . Проверьте вывод.

var expected = "Hof! Hof! Hof!";
var actual = dog.MakeNoise();
Assert.AreEqual(actual, expected);

Если метод находится внутри тестируемого класса, это деталь реализации. Возможно, вы захотите проверить взаимодействия , если в вашем классе есть соавтор, и вы хотите, чтобы ваши тесты Animal были изолированы от соавтора (возможно, Bar). Тогда вы можете выбрать использование подделки Bar, чтобы убедиться, что Animal действует надлежащим образом (и, конечно, у вас будут соответствующие тесты для real Bar). Если это ближе к вашему реальному вопросу, пожалуйста, обновите его.

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

class Animal
{
    public virtual string MakeNoise() { return whatever; }
}

class Dog : Animal 
{
    public override string MakeNoise() { return "Hof! Hof! Hof!"; }
}

//
Animal dog = new Dog();
var noise = dog.MakeNoise();

Вы даже можете зайти так далеко, чтобы сделать Animal абстрактным.

1 голос
/ 02 сентября 2011

Хотя я согласен с @jgauffin, юнит-тест на самом деле не должен вести себя так, но есть грязный способ сделать это независимо.

Сначала определите свой метод Барка virtual . Затем переопределите его в наследующем классе, который является частью вашего набора тестов.

public class AnimalTestClass : Animal
{
     public bool BarkCalled{get;set;}

     public override string Bark()
     {
          BarkCalled = true;
          return base.Bark();
     }
}

Затем в вашем тестовом методе создайте экземпляр этого класса

 [TestMethod]
 public void MakeNoise_WithAnimalTypeDog_CallsBarkMethod()
 {

     var dog = new AnimalTestClass(){AnimalType="dog"};
     dog.MakeNoise();

     // How can I test if the MakeNoise method called BarkMethod ?
     Assert.IsTrue(dog.BarkCalled);
 }

Редактировать: Исправлена ​​опечатка кода (забыл позвонить base.Bark ())

1 голос
/ 02 сентября 2011

Вы никогда не должны проверять, вызывает ли определенный метод другой метод.Реальная реализация никогда не должна быть интересной.

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

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