1

Тема: Що таке mock та stub?

Добрий день

Не підскажите що таке – mock/stub the database and IO devices.
І як його реалізувати?


Завдання: Implement a simple point of sale.
Assume you have:
– one input device: bar codes scanner
– two output devices: LCD display and printer
Implement:
– single product sale: products bar code is scanned and:
– if the product is found in products database than it's name and price is printed on LCD
– if the product is not found than error message 'Product not found' is printed on LCD
– if the code scanned is empty than error message 'Invalid bar-code' is printed on LCD
– when 'exit' is input than receipt is printed on printer containing a list of all previously scanned items names and prices as well as total sum to be paid for all items; the total sum is also printed on LCD display
Rules:
– use only SDK classes and your favorite test libraries
– mock/stub the database and IO devices
– concentrate on proper design and clean code, rather than supplying fully functioning application

2

Re: Що таке mock та stub?

не підкажете код ?

3

Re: Що таке mock та stub?

use only SDK classes and your favorite test libraries

ніколи не юзав ніяких бібліотек для тестування і не розумію, нащо вони

4 Востаннє редагувалося Lokki (21.05.2016 19:54:56)

Re: Що таке mock та stub?

Main

public class Main {

    public static void main(String[] args) {

        SalePoint salePoint = new SalePoint();

        Stack<String> inputArguments = new Stack<String>();
        inputArguments.push("0000000001");
        inputArguments.push("0000000002");
        inputArguments.push("0000000003");
        inputArguments.push("");
        inputArguments.push("exit");

        while(!inputArguments.isEmpty()){
            salePoint.getCodesScanner().write(inputArguments.pop());
        }

        salePoint.run();

    }
}

SalePoint,java

public class SalePoint {
    private InputDevice codesScanner = new CodesScanner();
    private OutputDevice lcdDisplay = new LCDDisplay();
    private OutputDevice printer = new Printer();

    private List<Product> products = new ArrayList<Product>();

    public SalePoint(){
        Inventory.buildInventory();
    }

    public InputDevice getCodesScanner() {
        return codesScanner;
    }

    public List<Product> getProducts() {
        return products;
    }

        public void run() {
        Product product;
        String barCode;
        while((barCode = codesScanner.read()) != null) {
            switch (barCode) {
                case "":
                    lcdDisplay.printError("Invalid bar-code");
                    break;
                case "exit":
                    printProductsAndTotalPrice();
                    return;
                default:
                    product = Inventory.getProduct(barCode);
                     if (product == null) {
                         lcdDisplay.printError("Product not found");
                     }else {
                         lcdDisplay.print(product);
                         products.add(product);
                     }
            }
        }

    }

    private void printProductsAndTotalPrice() {
        double summ = 0.0;

        for (Product product :
                products)
            summ += product.getPrice();

        lcdDisplay.println("Total:\t\t\t" + summ);
        printer.println("List of products:");
        printer.println("Name\t\t\tPrice");
        printer.print(products);
        printer.println("Total:\t\t\t" + summ);

        products.clear();
    }
}

Весь код я думаю немає смисла кидати.

5

Re: Що таке mock та stub?

Lokki написав:

Не підскажите що таке – mock/stub the database and IO devices.

Трохи бюрократично: функції, пов'язані з обміном із базою даних та пристроями введення-виведення, не реалізовувати, обмежившися функціями-заглушками чи імітацією їхньої роботи.
Тобто там, де вам треба отримати щось з БД, пишете на кшталт

data = getFromBDStub();

а функцію getFromBDStub робите з одного рядка - return якийсь зразок даних.

Подякували: Lokki, Torbins, leofun01, iovchynnikov4

6

Re: Що таке mock та stub?

Дякую.  А я думав це щось повязано з тестами :)

7

Re: Що таке mock та stub?

Взагалі кажучи, пов'язано, але не напряму - для автоматизованого тестування якраз так і роблять.

8

Re: Що таке mock та stub?

FakiNyan написав:

use only SDK classes and your favorite test libraries

ніколи не юзав ніяких бібліотек для тестування і не розумію, нащо вони

Та Ви у нас взагалі цікавий :)
Женерікі - непотрібна фігня, бібліотеки до тестування теж.
Ключове тут "ніколи не юзав" і "не розумію". Думаю, якщо усі девелопери ними користуються, то якийсь сенс таки є, правда?
Раджу Вам шукати сенс і досягати розуміння, а не відкидати усе, що спочатку не зрозуміле.

А поза тим, цей коментар несе рівно 0 інформації по темі, нащо Ви це написали?

Подякували: Master_Sergius, leofun012

9

Re: Що таке mock та stub?

koala написав:
Lokki написав:

Не підскажите що таке – mock/stub the database and IO devices.

Трохи бюрократично: функції, пов'язані з обміном із базою даних та пристроями введення-виведення, не реалізовувати, обмежившися функціями-заглушками чи імітацією їхньої роботи.
Тобто там, де вам треба отримати щось з БД, пишете на кшталт

data = getFromBDStub();

а функцію getFromBDStub робите з одного рядка - return якийсь зразок даних.

Все вірно, це типовий стаб. Створюючи стаб, ви визначаєте дані, які ви очікуєте від реально об'єкту.
Натомість, мокуючи об'єкт, ви визначаєте поведінку, яку очікуєте від реального об'єкту.
Ось приклад для розуміння:

interface MyDataAccessObject {
    User getUser(String userid);
}

class StubMyDataAccessObject {
    public User getUser(String userId) {
        return new User("Ivan", "Pasichnik");
    }
}

public class Test {
    public void testStub() {
        MyDataAccessObject stub = new StubMyDataAccessObject();
        // testing using stub
        assertTrue(stub.getUser("12").getName(), "Ivan"); ~~~ true
    }

    // mock using mockito
    public void testMock() {
        MyDataAccessObject mock = mock(MyDataAccessObject.class);
        when(mock.getUser(any(String.class))).thenReturn(new User("Ivan", "Pasichnik"));

        assertEquals(mock.getUser("12").getName(), "Ivan"); ~~~~ true
    }
}

Дуже гарно розписано для розуміння тут: http://stackoverflow.com/a/17810004/2180005

Подякували: Lokki, leofun012

10

Re: Що таке mock та stub?

FakiNyan написав:

use only SDK classes and your favorite test libraries

ніколи не юзав ніяких бібліотек для тестування і не розумію, нащо вони

Я зовсім не здивований.

По темі:
Поки хіба додам трішки поняття про mock/stub. Як сказали панове вище, це дійсно широко застосовується в автоматичному тестуванні та юніттестах. Наприклад, вам потрібно протестувати функцію, яка знаходить усі посилання в HTML коді певної сторінки. Хіба для перевірки правильності роботи функції потрібно щоразу завантажувати з мережі сторінку? А якщо ви раптом офлайн? Ось тому тут можна використати - stub - заглушку, яка на будь-який ваш запит буде повертати уже підготовлений html код, який ваша функція буде парсати. Якщо ж вам потрібна не проста заглушка, а яка ще може видавати різні відповіді на різні запити, то це вже називається - mock.

Подякували: leofun011

11

Re: Що таке mock та stub?

Master_Sergius написав:
FakiNyan написав:

use only SDK classes and your favorite test libraries

ніколи не юзав ніяких бібліотек для тестування і не розумію, нащо вони

Я зовсім не здивований.

По темі:
Поки хіба додам трішки поняття про mock/stub. Як сказали панове вище, це дійсно широко застосовується в автоматичному тестуванні та юніттестах. Наприклад, вам потрібно протестувати функцію, яка знаходить усі посилання в HTML коді певної сторінки. Хіба для перевірки правильності роботи функції потрібно щоразу завантажувати з мережі сторінку? А якщо ви раптом офлайн? Ось тому тут можна використати - stub - заглушку, яка на будь-який ваш запит буде повертати уже підготовлений html код, який ваша функція буде парсати. Якщо ж вам потрібна не проста заглушка, а яка ще може видавати різні відповіді на різні запити, то це вже називається - mock.

Строго кажучи, не треба покладатися на те, чи Ви офлайн/онлайн. Варто спирати кожен юніт тест на принципи FIRST: Fast, Independent, Repeatable, Self-validating, Timely. Власне літерка I = Independent, каже, що "The data used in a test should not depend on the environment in which the test is running. All the data needed for a test should be arranged as part of the test.", тож добре написаний тест не має спиратися на якусь визначену базу даних у мережі або сторінку взагалі.

Щодо того, що мокі дають можливість більш гнучко задавати логіку, також не згоден. Що Вам заважає реалізувати таку ж саму логіку у стабі? Ще й до того без різних специфічних методів where().thenReturn(), чистою джавою.
Різниця у тому, що це різні підходи до тестування: Mocks vs Stubs = Behavioral testing vs State testing (саме таку б відповідь очікували від Вас на співбесіді на >= middle developer). Не буду повторюватися, тут http://stackoverflow.com/a/17810004/2180005 ідеально все розписано.