2013-05-15 4 views
1

У меня есть вызов метода, который я тестирую на модуле. Внутри этого метода вызов вызывает вызов метода, который будет вызывать ошибку, потому что он пытается поговорить с устройством, которое не будет доступно при выполнении модульного теста. Есть ли способ избежать вызова внутреннего метода?Как пропустить вызов метода внутри внутри метода, который тестируется модулем

Окружающая среда: C# модульного тестирования Visual Studio 2010 в IDE

ответ

2

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

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

Мы можем быть Вам в состоянии помочь, если вы предоставите более подробную информацию об этом недоступном устройстве.

+0

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

1

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

public void DoSomething(int number, bool skipMethod= false) 
{ 
    if(!skipMethod) 
     MethodThatWillBreak(); 
{ 

Так что в процессе бега, это будет хорошо, но в тестовом модуле вы можете сделать

DoSomething(2,true); 

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

+1

Семантика здесь немного. Если переименовать callMethod в skipMethod, как вы его написали. – Pete

+0

Правильно, сэр –

0

Чтобы правильно протестировать устройство, вы должны отключить связь с устройством из класса, который хотите проверить! Абстрактное разделение на устройство в другом классе, реализующее интерфейс, вводящий класс связи в ctor тестируемого объекта, теперь вы можете вводить макетную реализацию извне и избегать ошибки, реализация mmock также может вести к ней вызов журнала или реагировать на предопределенный способ ослабления теста. Прочитайте зависимую инъекцию и инверсию управления

0

Обычно вы извлекаете внешние зависимости из тестируемого вами класса и обмениваете их поддельными в своем модульном тесте. Вы должны изолировать их и проверить интересующую вас часть. Я рекомендую вам взглянуть на Inversion of Control, а также на одну из многих Mocking Framework (Moq, Rhino Mocks и т. Д.)

4

Если вы тестируете устройство класс с внешними зависимостями, то вы должны изолировать внешние зависимости, используя интерфейс, который впрыскивается в

interface IDevice 
{ 
    void Run(); 
} 

interface IDeviceOperator 
{ 
    void Operate(); 
} 

class DeviceOperator : IDeviceOperator 
{ 
    private readonly IDevice _device; 

    public DeviceOperator(IDevice device) 
    { 
     _device = device; 
    } 

    public void Operate() 
    { 
     _device.Run(); 

     // test other stuff here 
    } 
} 

[TestFixture] 
public class DeviceOperatorTests 
{ 
    [Test] 
    public void Test_DeviceOperator_Operate() 
    { 
     IDevice device = A.Fake<IDevice>(); // Using FakeItEasy 3rd party mocking framework syntax 
     DeviceOperator deviceOperator = new DeviceOperator(device); 

     deviceOperator.Operate(); 
    } 
} 
1

Заканчивать Working Effectively with Legacy Code книги Майкла перьев. - это очень много предложений по работе с кодом, который не имеет блока еще тест.

Возможные подходы, описанные в книге:

  • экстракт зависимостей в интерфейсе - идеальный подход (см ответ jamespconnor в)
  • использовать флаг, чтобы обойти вызов (см ответ Колм Prunty в)
  • экстракт, который называют в виртуальный метод и переопределение в производном классе, используемом в модульном тесте
  • передать делегат (может быть меньше воздействия, чем полный интерфейс/вывод)

Образец для получения из класса:

public class WithComplexDependency 
{ 
    public void DoSomething() 
    { 
    // Extract original code into a virtual protected method 
    // dependency.MethodThatWillBreak(); 
    CallMethodThatWillBreak(); 
    } 

    virtual protected void CallMethodThatWillBreak() 
    { 
     dependency.MethodThatWillBreak(); 
    } 
} 

в тестовом коде являются производными от класса и обеспечить собственную реализацию:

public class WithMockComplexDependency : WithComplexDependency 
{ 
    // may also need to add constructor to call original one. 

    override protected void CallMethodThatWillBreak() 
    { 
     // do whatever is needed for your test 
    } 
} 

... 
WithComplexDependency testObject = new WithMockComplexDependency(); 
testObject.DoSomething(); // now does not call dependency.MethodThatWillBreak() 
... 
0

Вы, вероятно, не хотите пропустить внешние. Вместо этого вы хотите изолировать внешние зависимости, такие как доступ к внешним устройствам. Есть много способов сделать это a. Вы можете использовать платформу изоляции третьей части, такую ​​как Moq или RhinoMock, и т. Д. b. Вы можете использовать Moles framework (поскольку вы используете VS2010) - замените .NET-метод делегатом http://research.microsoft.com/en-us/projects/moles/ c. Платные системы изоляции, такие как TypeMock. d. Или просто написанная вручную поддельная реализация, которая использует в интерфейсе, и ваш тест использует реализацию Fake.

Смежные вопросы