2016-04-04 2 views
1

Скажем, у меня есть методы A, B, C и D.Пропустить внутренние вызовы методов в модульном тестировании

public bool A (int foo) 
{ 
    bool result = false; 
    if (foo > 0) 
     result = B(); 
    else result = C(); 
    D(foo); 
    return result; 
} 

Я хочу написать модульный тест для А, с вызовом B или C, но хочу пропустите вызов D (потому что это метод, использующий внешние службы). Можно ли пропустить вызов D с помощью некоторых атрибутов? Или высмеивать D, заменяя его каким-то поддельным сервисом?

+0

Вы должны * mock * 'D': вы не можете избежать вызова' D', если вы введете метод 'A' –

+0

Да, вам нужно будет Mock * D *. – bit

+0

В любом случае, вы хотите пропустить вызов 'D' - сама проблема. Вы не хотите изменять свое устройство, иначе это не настоящий тест. Ваш тест должен обрабатывать блок кода как часть черного ящика. «Я даю ему этот вклад, я ожидаю этот результат». –

ответ

1

Вам необходимо сделать класс, который имеет метод A(), зависит от внешних служб, используемых методом D(). Вы можете использовать любой из шаблонов DI, чтобы сделать это, хотя инъекция конструктора, вероятно, является лучшей отправной точкой.

Как только вы попадете в эту ситуацию, внешняя служба (службы) D() зависит от того, может ли она быть подделана и введена в класс. Тестирование теперь находится под вашим контролем через поведение поддельных (-ов).

Что-то вроде:

class Thing 
{ 
    private IExternalService _externalService; 

    public Thing(IExternalService externalService) 
    { 
     _externalService = externalService; 
    } 

    public void A() { ... } 

    public void D(string foo) 
    { 
     _externalService.DoSomeStuff(); 
    } 
} 

Тогда:

[Fact] 
public void TestThisOut() 
{ 
    var fakeExternalService = new MockFramework.CreateMock(); 
    fakeExternalService 
     .ShouldDoSomethingWhen(s => s.DoSomeStuff()) 
     .IsCalled(); 

    var testThing = new Thing(fakeExternalService); 

    testThing.A(); 

    Assert.That(testThing, Did.Some.Thing()); 
} 
1

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

public class TestableClass 
{ 
    private ICommunications _comms; 
    public TestableClass(ICommunications comms) 
    { 
     _comms = comms; 
    } 

    public bool FunctionToTest() 
    { 
     //do something testable 

     _comms.SomeFunction();//mocked object in unit tests 

     //do something else testable 
    } 
} 

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

0

Вам нужно издеваться метод D. Я написал пример, используя Typemock Изолятор, посмотрите:

class Methods 
{ 
    public bool A(int foo) 
    { 
     bool result = false; 
     if (foo > 0) 
      result = B(); 
     else 
      result = C(); 
     D(foo); 
     return result; 
    } 

    public void D(int foo) {throw new NotImplementedException();} 

    public bool C() { return false;} 

    public bool B() { return true;} 
} 

И тест:

[TestMethod, Isolated] 
public void TestIgnoreD() 
{ 
    //Arrange 
    Methods methods = new Methods(); 
    Isolate.WhenCalled(() => methods.D(0)).IgnoreCall(); 

    //Act 
    bool result = methods.A(1); 

    //Assert 
    Assert.IsTrue(result); 
} 

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

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

  • Нет связанных вопросов^_^