Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
opi.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.81 Mб
Скачать

Використання бібліотеки Moq

Moq – це платформа, яка прискорює, полегшує і спрощує створення імітованих реалізацій.

Перевага застосування засоби створення імітованих реалізацій в тому, що він дозволяє створювати такі реалізації тільки з тією функціональністю, яка покликана допомогти у виконанні тестів.

Модульне тестування працює найбільш успішно, коли тести невеликі за обсягом і цілеспрямовані, а всі інші компоненти максимально прості.

Створення імітованої реалізації за допомогою Moq складається з двох етапів.

Перший етап – створення нового об'єкту Моск < Т >, де Т - тип, імітовану реалізацію якого потрібно створити:

Mock<Graph> mock = new Mock<Graph>();

Другий етап – визначення поведінки, яке має демонструвати наша реалізація. Moq автоматично реалізує всі методи і властивості переданого їй типу, але виконує це, використовуючи значення за замовчуванням для відповідних типів. Наприклад, метод IProductRepository . GetProducts повертає порожній об'єкт IEnumerable < Product >. Щоб змінити спосіб, яким Moq реалізує член типу, потрібно скористатися методом Setup:

mock.Setup(m => m.GetNodeArray()).Returns(nodeArray);

Щоб вказати на необхідність використання об’єкту Moq для імітації об’єкту Graph можна скористатись прив’язкою ninject:

ninjectKernel.Bind<Graph>().ToConstant(mock.Object);

При налаштуванні нової поведінки Moq повинні враховуватися три елементи, а саме:

  • використання селектора методу Moq;

  • використання фільтрів параметрів Moq;

  • повернення результату.

Використання селектора методу Moq

Перший елемент – обраний спосіб. Moq працює, використовуючи LINQ і лямбда-вирази. При виклику методу Setup засіб Moq передає інтерфейс, який був зазначений для реалізації. LINQ дозволяє вибрати метод, який потрібно конфігурувати або перевірити за допомогою лямбда-виразу. Тому, коли потрібно визначити поведінку для методу GetProducts , це здійснюється наступним чином:

mock.Setup (m => m.GetProducts ()). (<.. . інші методи ...>);

Ми не будемо заглиблюватися в подробиці того, як функціонує цей метод - просто знайте, що він працює, і застосовуйте його відповідним чином. Використовувати метод GetProducts просто, оскільки він не має параметрів. Якщо потрібно застосовувати метод, який приймає параметри, потрібно врахувати другий елемент: фільтр параметра.

Використання фільтрів параметрів Moq

Можна вказати, щоб Moq реагувала різним чином залежно від значень параметрів, що передаються методу. Метод GetProducts не приймає параметра, тому для пояснення ми використовуємо наступний простий інтерфейс:

public interface IMyInterface {

string ProcessMessage(string message);

}

У лістингу нижче показаний код, який створює імітовану реалізацію інтерфейсу з різною поведінкою для різних значень параметрів.

Mock < IMyInterface > mock = New Mock < IMyInterface > ();

mock.Setup (m => m.ProcessMessage ("hello")). Returns ("Hi there");

mock.Setup ( m => m.ProcessMessage ("bye")). Returns ("See you soon");

Moq інтерпретує ці оператори як інструкції для повернення рядка Hi There , коли параметром методу ProcessMessage є hello , і для повернення рядка See You Soon , коли значення параметра дорівнює bye . Для всіх інших значень параметрів Moq буде повертати значення за замовчуванням для типу результату методу - в даному випадку null , оскільки типом є string .

Установка відповідей для всіх можливих значень параметра може дуже швидко перетворитися на рутину. Це завдання стає стомлюючої і важкою, коли доводиться мати справу з більш складними типами, оскільки доводиться створювати об'єкти, які представляють всі ці типи, і застосовувати їх для порівнянь. На щастя. Moq надає клас It , який можна використовувати для представлення обширних категорій значень параметрів. Наприклад :

mock. Setup (m => т . ProcessMessage (It. IsAny <string> ())). Returns ("Message received");

Клас It визначає ряд методів, які використовуються з параметрами узагальненого типу. У даному випадку ми викликали метод IsAny , використовуючи string в якості узагальненого типу. Цей оператор вказує Moq , що, коли метод ProcessMessage викликається з будь-яким строковим значенням, він повинен повертати відповідь Message Received (Повідомлення отримано). Статичні методи, що надаються класом It , перераховані в таблиці 1.

Таблиця 1 - Статичні методи класу It

Метод

Опис

Is < T > ()

Виконує зіставлення на основі зазначеного предиката

IsAny < T > ()

Констатує відповідність, якщо параметр є будь-яким примірником типу Т

IsInRange < T >

Констатує відповідність , якщо значення параметра лежить в діапазоні між зазначеними значеннями

IsRegex

Констатує відповідність строкового параметра , якщо він відповідає вказаному регулярному виразу

Метод Is < T > є найбільш гнучким, оскільки дозволяє вказати предикат, який викликає відповідність параметра, якщо той повертає значення true , як показано в лістингу нижче:

mock.Setup (m => m.ProcessMessage (It.Is <string> (s => s == "hello" || s == "bye")))

. Returns ("Message received");

Цей оператор вказує Moq , що потрібно повернути рядок Message Received, якщо значенням параметра string є hello або bye .

Повернення результату

При налаштуванні поведінки це часто робиться для визначення результату, який метод буде повертати при його виклику. Усі попередні приклади пов'язували метод Returns з викликом Setup для повернення конкретного значення. Параметр, переданий імітували методом як параметр для методу Returns , можна застосовувати також для отримання виведення в залежності від введення. Ситуація подібного роду продемонстрована нижче:

mock.Setup (m => m. ProcessMeesage (It . IsAny <string> ()))

. Returns <string> (s => string.Format ("Message received: {0) ", s));

У се що ми виконуємо - це виклик методу Returns з параметром узагальненого параметр методу лямбда - висловом , що дозволяє генерувати динамічний результат - в даному випадку створити форматований рядок .

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]