2016-02-10 4 views
1

Есть ли способ с MOQ иметь последовательные вызовы метода возвращать разные параметры out? Для быстрого примера получая метод:Выделили метод вывода разного параметра из каждого вызова с помощью MOQ

public void OutputANumber(out int number) 

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

int number = 1; 
mock.Setup(n => n.OutputANumber(out number)); 
number = 2; 
mock.Setup(n => n.OutputANumber(out number)); 

Не работает как вторая установка отменяет первую, также является SetupSequence позволяет только для последовательного возвращения.

ответ

0

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

int number = 1; 
mock.Setup(n => n.OutputANumber(out number)).Callback(() => ChangeOut(mock)); 

void ChangeOut(Mock<type> mock) 
{ 
    int number = 2; 
    mock.Setup(n => n.OutputANumber(out number)); 
} 

или вы можете создать фиктивный объект, который отслеживает количество вызовов и выводит новое значение по мере необходимости.

0

Решение LukeW может работать, если вам нужно всего два последовательных вызова. Но с более длинной последовательностью он может стать слишком сложным. Вы можете решить это намного проще с Typemock Isolator. Взгляните на приведенный ниже пример:

public class ClassUnderTest 
{ 
    public void OutputANumber(out int number) 
    { 
     number = 3; 
    } 
} 

[TestMethod, Isolated] 
public void TestOutSequence() 
{ 
    //Arrange 
    var n = new ClassUnderTest(); 

    int number = 1; 
    Isolate.WhenCalled(() => n.OutputANumber(out number)).IgnoreCall(); 
    number = 2; 
    Isolate.WhenCalled(() => n.OutputANumber(out number)).IgnoreCall(); 
    Isolate.WhenCalled(() => n.OutputANumber(out number)).CallOriginal(); 

    //Act 
    var res1 = 0; 
    var res2 = 0; 
    var resOriginal = 0; 
    var resDefault = 0; 
    n.OutputANumber(out res1); 
    n.OutputANumber(out res2); 
    n.OutputANumber(out resOriginal); 
    n.OutputANumber(out resDefault); 

    //Assert 
    Assert.AreEqual(1, res1); 
    Assert.AreEqual(2, res2); 
    Assert.AreEqual(3, resOriginal); 
    Assert.AreEqual(3, resDefault); 
} 

Не нужно создавать фиктивные объекты или дополнительные методы. По последовательного определения из параметров и с помощью Isolate.WhenCalled() вы можете установить любую последовательность выходных параметров:

int number = 1; 
Isolate.WhenCalled(() => n.OutputANumber(out number)).IgnoreCall(); 

Последний вызов Isolate.WhenCalled() определяет поведение по умолчанию для метода с этого момента. Итак, в этом примере я вернул первоначальную реализацию, которая будет вызвана после поддельных вызовов:

Isolate.WhenCalled(() => n.OutputANumber(out number)).CallOriginal();