2016-08-15 4 views
3

Я новичок в использовании Moq и не тестировал устройство примерно через 5 лет. Многие вещи изменились.При использовании Moq, издеваются интерфейсы реализованные методы, которые должны выполняться?

Я пытаюсь обернуть голову вокруг основ.

У меня есть интерфейс.

public interface ILogger 
{ 
    void Log(string message) 
} 

И этот интерфейс реализован следующим образом.

Я тестирую следующую логику.

public class MyClass 
{ 
    public MyMethod(int z) 
    { 
     var logger = new MyLogger(); 

     if(z == 5) 
     { 
      logger.Log("it is true"); 

      return true; 
     } 

     logger.Log("it is false); 

     return false; 
    } 
} 

Мое испытание выглядит следующим образом.

[TestMethod] 
public void Test_MyMethod() 
{ 
    var mock = new Mock<ILogger>(); 

    mock.Setup(y => y.Log(It.IsAny<string>()).Verifiable(); 

    var o = new MyClass(); 

    var result = o.MyMethod(5); 

    Assert.IsTrue(result);   

    mock.Verify(); 

} 

Проблема, с которой я столкнулся, - это статический метод, вызываемый при реализации интерфейса ILogger.

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

Что я хотел бы сделать, так это то, что в любое время ILogger.Log он переопределяется и не вызывает этот статический метод.

Возможно ли это?

Неужели я об этом ошибаюсь?

ответ

4

Вы создаете макет на основе интерфейса ILogger, но вы не вводите Mock в свой MyClass экземпляр. Когда MyClass выполняет, он использует экземпляр Logger вместо вашего ILogger макета.

Рассмотрим что-то подобное для своего класса вместо:

public class MyClass 
{ 

    private ILogger logger; 
    public MyClass(ILogger loggerInstance) 
    { 
     logger=loggerInstance; 
    } 
    public MyMethod(int z) 
    { 

     if(z == 5) 
     { 
      logger.Log("it is true"); 

      return true; 
     } 

     logger.Log("it is false); 

     return false; 
    } 
} 

Обратите внимание, что в конструкторе MyClass вы теперь принимают экземпляр класса, который реализует интерфейс ILogger. Это позволяет вводить свой фиктивный объект вместо фактического бетона Logger:

[TestMethod] 
public void Test_MyMethod() 
{ 
    var mock = new Mock<ILogger>(); 

    mock.Setup(y => y.Log(It.IsAny<string>()).Verifiable(); 

    var o = new MyClass(mock.Object); 

    var result = o.MyMethod(5); 

    Assert.IsTrue(result);   

    mock.Verify(); 

} 

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

+0

Эй, спасибо, это работает. Наверное, я подслушиваю, что издевательство не носит более глобальный характер, но все в порядке. Первоначально я избегал ничего делать в конструкторе, потому что класс в этом экземпляре является контроллером, но этот шаблон все еще работает нормально. – moctopus

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