Модульное тестирование с использованием VS2010 - PullRequest
1 голос
/ 10 декабря 2011

Я тестирую модульный метод, скажем, ABC() как

myclass target = new myclass();
target.ABC();

Этот метод ABC (), в свою очередь, вызывает другой метод XYZ () из другого класса, такого как anotherclass.XYZ(), и этот метод XYZ ()входной параметр зависит от значений из текстовых полей.

Поскольку при запуске теста значения из текстового поля не передаются, я получаю исключение нулевой ссылки во время выполнения теста (я имею в виду, что тест завершается неудачей с исключением).

Аналогичная ситуация (другая): метод извлекает значение идентификатора из строки запроса, например

HttpContext context
id = context.request.querystring["id"]

Поскольку при выполнении теста значения этого идентификатора равны нулю, я получаю исключение нулевой ссылки (я имею в виду, что тест завершается неудачей с исключением)).

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

Я что-то не так делаю?

ИЛИ

Мой тест работает правильно?

Пожалуйста, предложите.Благодарим Вас за помощь.

Спасибо.

Ответы [ 2 ]

1 голос
/ 10 декабря 2011

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

Например, если у вас есть такой код:

MyClass{

  private AnotherClass _another = new AnotherClass();

  public string ABC(){
    return _another.XYZ();
  }
}

public AnotherClass{
  //Context comes from somewhere...
  public string XYZ(){
    return context.request.querystring["id"]
  }
}

Вы бы хотели изменить его на что-то вроде этого:

interface IAnotherClass{
  string XYZ();
}

MyClass{  
  private IAnotherClass _another = new AnotherClass();

  public MyClass(IAnotherClass anotherClass){
    _another = anotherClass;
  }

  public string ABC(){
    return _another.XYZ();
  }
}

public AnotherClass: IAnotherClass{
  //Context comes from somewhere...
  public string XYZ(){
    return context.request.querystring["id"]
  }
}

Затем вы можете использовать макет для макета IAnotherClass, как показывал IceN. Что касается HttpContext - это становится немного сложнее, но если он используется только в AnotherClass, вам не нужно его высмеивать, так как объект mock будет просто возвращать то, что вам нравится. Очевидно, что когда вы приходите тестировать AnotehrClass, это становится проблемой. Если вы обнаружите, что вам нужно высмеять его, есть несколько примеров того, что нужно делать - например, this one.

1 голос
/ 10 декабря 2011

Вам нужно использовать «не настоящий» экземпляр anotherclass, но Mocked экземпляр с ложной реализацией XYZ.

Я приведу пример с фреймворком Moq.

Mock<IAnotherclass> anotherClassMock= new Mock<IAnotherclass>();//create mock instanse
anotherClassMock.Setup(x=>x.XYZ);//add .Returns(something) if method XYZ returns some value
myclass target = new myclass(anotherClassMock.Object);//create instance of object under test with fake instance of anotherClassMock
target.ABC();
anotherClassMock.Verify(x=>x.XYZ);//verify that method XYZ is actualy been called

Прежде всего вам нужно извлечь интерфейс класса anotherclass, чтобы создать Mock. В моем примере я использовал интерфейс IAnotherclass.

Почему мы так поступаем? Мы не занимаемся логикой класса anotherclass. Мы предполагаем, что это правильно. Поэтому мы абстрагируемся от него и тестируем только логику myclass. И давайте только убедимся, что метод XYZ был вызван.

...