Как прокладить класс, который вызывается более одного раза в тестируемой функции с использованием подделок Microsoft

80
8

Предположим, что у меня есть класс, и у него есть GetList(), как это:


public class Foo
{
public List<Bar> GetList(string para);
}

И проверенная функция похожа на


public ResultType TestedFunc()
{
if( GetList("condition").count() == 1 )
{
//do arrange business
if( GetList("same condition as above".count() == 2 )
{
//do core business
}
else
{
return ResultType;
}
}
else
{
return ResultType
}
}

В моем методе тестирования я использую ShimFoo.AllInstance.GetList для выравнивания GetList(). Независимо от странной бизнес-логики и логики вызова, мой вопрос заключается в том, как я могу получить первый вызов GetList(), а второй вызов GetListh() возвращает разные результаты, например, списки, которые содержат соответственно один и два объекта.


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


Я прочитал три официальные статьи о MS Fake:


1. Изолировать код под тестом с подделками Microsoft


2. Использование заглушек для изоляции частей вашего приложения друг от друга для модульного тестирования


3. Использование прокладок для изоляции вашего приложения от других сборок для модульного тестирования


но я еще не нашел руководство, которое может сделать то, что я, как описано выше.


Я узнал, что проверка поведения может быть выполнена на макет теста, есть много фреймворков, которые могут достичь этого (например, google mock). Я могу определить, как работает класс mock, когда он вызывается первым/вторым/третьим временем, я могу установить последовательность для строгого ограничения класса mock. Интересно, может ли MS Fakes сделать то же самое.


Спасибо, ребята.

спросил(а) 2014-12-08T14:50:00+03:00 5 лет, 9 месяцев назад
1
Решение
90

Вы можете просто сохранить счетчик вызовов, захватив переменную int при настройке Shim.


[TestMethod]
public void TestMethod1()
{
using(ShimsContext.Create()) {
int counter = 0; // define the int outside of the delegate to capture it value between calls.

ShimFoo sfoo = new ShimFoo();
sfoo.GetListString = (param) =>
{
List<Bar> result = null;
switch (counter)
{
case 0: // First call
result = new Bar[] { }.ToList();
break;
case 1: // Second call
result = new Bar[] { new Bar() }.ToList();
break;
}
counter++;
return result;
};
Foo foo = sfoo.Instance;

Assert.AreEqual(0, foo.GetList("first").Count(), "First");
Assert.AreEqual(1, foo.GetList("second").Count(), "Second");
Assert.IsNull(foo.GetList("third"), "Third");
}
}

Или вы можете проверить передаваемый параметр и соответствующим образом скорректировать результат.


[TestMethod]
public void TestMethod1()
{
using(ShimsContext.Create()) {
ShimFoo sfoo = new ShimFoo();
sfoo.GetListString = (param) =>
{
List<Bar> result = null;
switch (param)
{
case "first": // First call
result = new Bar[] { }.ToList();
break;
case "second": // Second call
result = new Bar[] { new Bar() }.ToList();
break;
}
return result;
};
Foo foo = sfoo.Instance;

Assert.AreEqual(0, foo.GetList("first").Count(), "First");
Assert.AreEqual(1, foo.GetList("second").Count(), "Second");
Assert.IsNull(foo.GetList("third"), "Third");
}
}

ответил(а) 2014-12-08T14:56:00+03:00 5 лет, 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема