Alibaba открывает новое поколение Mock-инструментов для модульного тестирования!
Alibaba открывает новое поколение Mock-инструментов для модульного тестирования!

TestableMockОн улучшен на основе исходного кода и байт-кода.JavaМодульное Вспомогательный инструмент для обучения, включает в себя следующие функции:

  • Доступ к закрытым членам тестируемого класса: включить Модульное. тестирование может напрямую вызывать и получать доступ к частным членам тестируемого класса, решая проблемы инициализации частных членов и частных методов тестирования.
  • Произвольные вызовы Fast Mock: быстро заменяйте любые вызовы методов тестируемого класса методами Mock.,Реализуйте «замените место, куда вы указываете»,Решите громоздкую проблему использования традиционного Mockинструмента.
  • Вспомогательный метод testvoid: используйте Mock validator для проверки внутренней логики метода.,Решите проблему, заключающуюся в том, что метод сложно реализовать без возвращаемого значения. Модульное тестирование.

Доступ к закрытым полям и методам членов

В настоящее время споры о том, нужно ли проводить модульное тестирование частных методов, постепенно затихают, и общепринятая практика разработчиков дала фактический ответ. Во многих случаях сложно косвенно тестировать частные методы с помощью общедоступных. Разработчики предпочитают сделать изначально частные методы тестируемыми в тестовых примерах, изменив видимость метода.

Кроме того, при модульном тестировании часто необходимо инициализировать определенные поля-члены тестируемого объекта, но иногда из-за ограничений метода-конструктора тестируемого класса не представляется возможным удобно присвоить этим значениям значения. поля. Итак, можно ли разрешить коду в примере модульного тестирования иметь прямой доступ к частным методам и полям-членам тестируемого класса, не разрушая инкапсуляцию тестируемого типа? TestableMock предоставляет два простых решения.

Способ первый:использовать@EnablePrivateAccessаннотация

Просто длятест Добавление класса@EnablePrivateAccessаннотация,В сценарии использования вы можете получить следующие расширенные возможности тестирования:

  • Вызов частного метода тестируемого класса(включатьстатическийметод)
  • Чтение частных полей тестируемого класса(Включает статическое поле)
  • Измените частные поля тестируемого класса.(Включает статическое поле)
  • Измените константные поля тестируемого класса (поля, измененные с помощью Final,Включает статическое поле)

При доступе к частным постоянным членам и их изменении IDE может выдать синтаксические ошибки, но компилятор сможет нормально выполнить тест. (Используя улучшение кода во время компиляции, в настоящее время реализована только адаптация к языку Java)

Посмотрите эффектjava-demoПример проектаDemoPrivateAccessTestтест Варианты использования в классах。

методдва:использоватьPrivateAccessorинструментдобрый

Если вы не хотите видеть напоминание о синтаксической ошибке в среде IDE,Или в проекте JVM, отличном от Java (например, на языке Kotlin).,Вы также можете использоватьPrivateAccessorинструментдобрыйдля прямого доступа к частным членам。

Этот класс предоставляет 6 статических методов:

  • PrivateAccessor.get(проверяемый объект, «Имя частного поля») ➜ Чтение частных полей тестируемого класса
  • PrivateAccessor.set(тестируемый объект, «Имя частного поля», новое значение) ➜ Измените частные поля (или постоянные поля) тестируемого класса.
  • PrivateAccessor.invoke(проверяемый объект, «Имя частного метода», Параметры вызова..) ➜ Вызов частного метода тестируемого класса
  • PrivateAccessor.getStatic(проверяемый тип, "Имя частного статического поля") ➜ Прочитать тестдобрыйизстатическийличное поле
  • PrivateAccessor.setStatic(проверяемый тип, "Имя частного статического поля", новое значение) ➜ Изменить проверенноедобрыйизстатическийличное поле(илистатическийпостоянные поля)
  • PrivateAccessor.invokeStatic(проверяемый тип, "Имя частного статического метода", Параметры вызова..) ➜ вызовпроверенодобрыйизстатическийчастныйметод

Быстро имитируйте любой вызов метода тестируемого класса.

По сравнению с предыдущим методом Mock, Mock использует классы в качестве детализации.,TestableMockПозвольте пользователям напрямую определять потребностиMockиз单个метод,и следуйте принципу соглашения над конфигурацией,Автоматически заменять указанные вызовы методов в тестируемом методе во время выполнения в соответствии с правилами.

Подводя итог, их два:

  • Метод, не являющийся конструктором,Скопируйте исходное определение метода в тестовый класс.,Добавьте параметр того же типа, что и вызывающий объект,добавлять@MockMethodаннотация
  • Метод ложного строительства,Скопируйте исходное определение метода в тестовый класс.,Измените возвращаемое значение на сконструированный тип,Имя метода произвольное,добавлять@MockContructorаннотация

Конкретное соглашение об определении метода Mock выглядит следующим образом:

1. Переопределить вызовы методов любого класса.

существоватьтестдобрыйвнутриопределить@MockMethodаннотацияиз普通метод,Сделайте его точно таким же, как имя метода, параметры и тип возвращаемого значения, которые необходимо переопределить.,Затемсуществовать Чтопараметр Добавлено в начало спискадобавлятьодиндобрый Типметодизначально принадлежалвернослондобрый型изпараметр。

В это время все вызовы переопределяемого метода в тестируемом классе будут автоматически заменены вызовами вышеупомянутого пользовательского метода Mock при запуске модульного теста.

Уведомление:При столкновении с перезаписьюметод Когда есть повторяющиеся имена,可以将需覆写изметодимя, написанное для@MockMethodаннотацияизtargetMethodпараметрвнутри,Таким образом, сам метод Mock может быть назван произвольно.

Например,проверенодобрый Есть место в"anything".substring(1, 2)вызов,Мы надеемся изменить его на фиксированную строку при запуске теста.,Затем просто определите следующий метод в тестовом классе:

Язык кода:javascript
копировать
// Исходная сигнатура метода — `String substring(int, int)`
// Объект «что-нибудь», для которого вызывается этот метод, имеет тип «String».
// Затем сигнатура метода Mock добавляет параметр типа String (имя произвольное) в начало списка параметров.
// Этот параметр можно использовать для получения значения и контекста фактического вызывающего абонента в данный момент.
@MockMethod
private String substring(String self, int i, int j) {
    return "sub_string";
}

Следующий пример показываетtargetMethodпараметр Использование,Эффект тот же, что и в приведенном выше примере:

Язык кода:javascript
копировать
// Используйте targetMethod, чтобы указать имя метода, который будет издеваться.
// Сам метод теперь можно назвать как угодно, но параметры метода по-прежнему должны соответствовать тем же правилам соответствия.
@MockMethod(targetMethod = "substring")
private String use_any_mock_method_name(String self, int i, int j) {
    return "sub_string";
}

Посмотреть полный пример кодаjava-demoиkotlin-demoПример проектасерединаизshould_able_to_mock_common_method()тествариант использования。(потому чтоKotlinверноStringдобрый Модель была магически модифицирована.,ПоэтомуKotlin示例середина将проверенометодсуществоватьBlackBoxдобрыйвнутридобавлятьслой упаковки)

2. Переопределить методы-члены самого тестируемого класса.

Иногда при тестировании определенных методов вы хотите смоделировать другие методы-члены тестируемого класса.

Метод операции такой же, как и в предыдущем случае. Первый тип параметра метода Mock должен совпадать с типом тестируемого класса, чтобы можно было переопределить метод-член самого тестируемого класса (публичный или частный). .

Например,проверенодобрыйсередина有один Подписано какString innerFunc(String)изчастныйметод,Мы хотим заменить его, когда тест,Затем просто определите следующий метод в тестовом классе:

Язык кода:javascript
копировать
// Тестируемый тип — «DemoMock».
// Поэтому при определении метода Mock добавьте параметр типа DemoMock (имя произвольное) в начало параметра целевого метода.
@MockMethod
private String innerFunc(DemoMock self, String text) {
    return "mock_" + text;
}
3. Переопределить статические методы любого класса.

Mock для статического метода такой же, как и для обычного метода. Но что нужно Уведомлению, так это,Когда вызывается метод Mock статического метода,Первый прошел впараметр Фактическое значение всегдаnull

Например,существоватьпроверенодобрыйсерединавызов ПонятноBlackBoxдобрый型серединаизстатическийметодsecretBox(),изменятьметод Подписано какBlackBox secretBox(),Метод Mock заключается в следующем:

Язык кода:javascript
копировать
// Целевой статический метод определен в типе BlackBox.
// При определении метода Mock добавьте параметр типа BlackBox (имя произвольное) в начале параметра целевого метода.
// Этот параметр используется только для определения типа цели, фактическое входящее значение всегда будет нулевым.
@MockMethod
private BlackBox secretBox(BlackBox ignore) {
    return new BlackBox("not_secret_box");
}

Посмотреть полный пример кодаjava-demoиkotlin-demoПример проектасерединаизshould_able_to_mock_static_method()тествариант использования。

Методы тестирования без возвращаемых значений

Как тестировать методы типа void, всегда было темой, которую многие платформы модульного тестирования незаметно избегали. Поскольку предыдущие методы модульного тестирования в основном проверяли возвращаемые результаты тестируемого модуля, ситуация изменится, когда метод не возвращает значение. Нет. способ начать.

С функциональной точки зрения, хотя метод void не возвращает никакого значения, его выполнение определенно окажет некоторое потенциальное влияние на внешний мир. Мы называем это «побочным эффектом» метода, например:

  1. Инициализировать некоторую внешнюю переменную (частный член переменная или глобальная статическаяпеременная)
  2. Назначьте экземпляр внешнего объекта в теле метода.
  3. Вывод журнала
  4. Другие внешние методы назывались
  5. … …

Метод, который не возвращает никакого значения и не производит никаких «побочных эффектов», не имеет смысла.

Эти"побочный эффект"из本质归纳来说可分为两добрый:Изменить внешние переменныеиВызов внешнего метода

Благодаря доступу к частным полям TestableMock и валидатору Mock вы можете легко проверить результаты «побочных эффектов».

1. Измените метод void внешних переменных.

Например,Этот нижеметод会根据输入修изменятьчастный成员переменнаяhashCache

Язык кода:javascript
копировать
class Demo {
    private Map<String, Integer> hashCache = mapOf();

    public void updateCache(String domain, String key) {
        String cacheKey = domain + "::" + key;
        Integer num = hashCache.get(cacheKey);
        hashCache.put(cacheKey, count == null ? initHash(key) : nextHash(num, key));
    }

    ... // Другие методы опущены
}

Чтобы протестировать этот метод, вы можете использовать TestableMock, чтобы напрямую прочитать значение частной переменной-члена и проверить результат:

Язык кода:javascript
копировать
@EnablePrivateAccess  // Включить функцию доступа к частным участникам TestableMock
class DemoTest {
    private Demo demo = new Demo();

    @Test
    public void testSaveToCache() {
        Integer firstVal = demo.initHash("hello"); // доступ к частным методам
        Integer nextVal = demo.nextHash(firstVal, "hello"); // доступ к частным методам
        demo.saveToCache("demo", "hello");
        assertEquals(firstVal, demo.hashCache.get("demo::hello")); // читать личноепеременная
        demo.saveToCache("demo", "hello");
        assertEquals(nextVal, demo.hashCache.get("demo::hello")); // читать личноепеременная
    }
}
2. Вызовите метод void внешнего метода.

Например, следующий метод выводит информацию на консоль на основе ввода:

Язык кода:javascript
копировать
class Demo {
    public void recordAction(Action action) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss ");
        String timeStamp = df.format(new Date());
        System.out.println(timeStamp + "[" + action.getType() + "] " + action.getTarget());
    }
}

Чтобы протестировать этот метод,можно использоватьTestableMockбыстрыйMockТерятьSystem.out.printlnметод。существоватьMockметодтеловнутриможно продолжать Выполнить исходный вызов(Это эквивалентно не влиянию на оригинал.метод Функция,Используется только для записи разговоров),Вы также можете оставить это поле пустым (что эквивалентно удалению побочных эффектов исходного метода).

После выполнения тестируемого метода типа void,использоватьInvokeVerifier.verify()Убедитесь, что входящее содержимое печати соответствует ожиданиям.:

Язык кода:javascript
копировать
class DemoTest {
    private Demo demo = new Demo();

    // Перехват вызовов `System.out.println`
    @MockMethod
    public void println(PrintStream ps, String msg) {
        // Выполнить исходный вызов
        ps.println(msg);
    }

    @Test
    public void testRecordAction() {
        Action action = new Action("click", ":download");
        demo.recordAction();
        // Убедитесь, что вызывается метод Mock `println` и переданные параметры соответствуют ожиданиям.
        verify("println").with(matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} \\[click\\] :download"));
    }
}

Адрес проекта

Адрес с открытым исходным кодом: https://gitee.com/mirrors/TestableMock.

Следите за публичной учетной записью WeChat Тджун , ответить после подписки mock  Получите документацию по использованию инструмента-макета.

Язык кода:javascript
копировать
Как получить: 1. Отсканируйте QR-код ниже 2. сосредоточиться а затем ответьте «mock», чтобы скачать.

Почему фрагменты кода на StackOverflow разрушат ваш проект?

2020-12-31

Интранет Alibaba объявил, что отменит систему «361»! Сотрудники допрошены: меняют суп, но не лекарства

2020-12-31

Я слышал, что другого брата избили за использование ГГГГ-ММ-дд...

2020-12-30

FFmpeg отмечает свое 20-летие! В одиночку поддержите бесчисленное количество игроков по всему миру!

2020-12-30

Полезны ли ночные перекусы? Тогда почему ты не можешь просто съесть это? Краткое обсуждение инцидента с ночным перекусом с участием сотрудников Huawei

2020-12-29

Углубленное общение

технология + общество

Рабочее место + Предпринимательство

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose