2016-02-19 6 views
0

Я новичок пытается издеваться вещи в модульных тестов ...Как издеваются вызов функции в методе тестирования я - в настоящее время с помощью NSubsitute

Пример кода упрощена для размещения:

namespace MockInvestigate.Monitor 
{ 
    internal interface IAgentRepo 
    { 
     Dictionary<string, string> GetAgentAppSettings(string moduleName); 
    } 

    public class AgentRepo : IAgentRepo 
    { 
     public virtual Dictionary<string, string> GetAgentAppSettings(string moduleName) 
     { 
      return new Dictionary<string, string> { { "real", "data" } }; 
     } 
    } 
} 

Это метод, который я хочу модульное тестирование - но переопределить вызов GetAgentAppSettings

namespace MockInvestigate 
{ 
    public class Class1 
    { 
     public static bool IsInitialized(string taskName) 
     { 
      AgentRepo ar = new AgentRepo(); 
      var arReturn = ar.GetAgentAppSettings(taskName); 

      return arReturn.ContainsKey("real"); 
     } 
    } 
} 

тест блока - пытается издеваться вызовом «GetAgentAppSettings»

[TestMethod] 

public void TestMethod1() 
{ 
var repo = Substitute.ForPartsOf<AgentRepo>(); 
var appReturn = new Dictionary<string, string> { { "bogus", "bogus2" } }; 
repo.GetAgentAppSettings("somevalue").ReturnsForAnyArgs(appReturn); 

bool retValue = Class1.IsInitialized("somevalue"); 

Assert.IsFalse(retValue); 
} 

Когда мой тест запускается, реальная GetAgentAppSettings называется, возвращая «реальные», «данные», а не фиктивные данные, которые я хочу. Я пробовал .When(...).DoNotCallBase().

Можно ли изменить мой тест на работу? Требуется ли изменить базовый код для работы?

Любая помощь будет оценена по достоинству.

+0

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

ответ

1

Создав замену repo, вы должны ввести ее внутрь Class1. В вашем коде, однако, вы создаете AgentRepo внутри метода IsInitialized, поэтому он не использует замену, созданную вами в методе тестирования.

Вы должны ввести замену путем инъекции конструктора, инъекции свойств или инъекции метода.

Как следует из названия, впрыск конструктора - это когда вы вводите зависимость от конструктора. Поскольку метод IsInitialized является статическим, это не вариант.

Аналогично, вложение свойств использует свойства для ввода зависимостей. Вы могли бы создать статическое свойство, но обычно избегаете его. Он всегда будет использовать один и тот же экземпляр для каждого потока, поэтому вы должны гарантировать, что AgentRepo является потокобезопасным.

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

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