Я написал несколько тестов для статического метода. Статический метод принимает только один аргумент. Тип аргумента является окончательным классом. С точки зрения кода:
public class Utility {
public static Optional<String> getName(Customer customer) {
// method's body.
}
}
public final class Customer {
// class definition
}
Итак, для Utility
класса я создал тестовый класс, UtilityTests
в котором я написал тесты для этого метода getName
. Основой модульного тестирования является TestNG, а используемая библиотека - mocking Mockito
. Таким образом, типичный тест имеет следующую структуру:
public class UtilityTests {
@Test
public void getNameTest() {
// Arrange
Customer customerMock = Mockito.mock(Customer.class);
Mockito.when(...).thenReturn(...);
// Act
Optional<String> name = Utility.getName(customerMock);
// Assert
Assert.assertTrue(...);
}
}
В чем проблема ?
Принимая во внимание, что тесты успешно выполняются локально, внутри IntelliJ они терпят неудачу на Jenkins (когда я помещаю свой код в удаленную ветку, запускается сборка и в конце запускаются модульные тесты). Сообщение об ошибке выглядит следующим образом:
org.mockito.exceptions.base.MockitoException: не может издеваться / шпионский класс com.packagename.Customer Mockito не может издеваться / шпионить, потому что: - последний класс
Что я пробовал?
Я немного искал, чтобы найти решение, но не смог. Я отмечаю здесь, что мне не разрешено менять тот факт, что Customer
это последний класс. В дополнение к этому, я хотел бы, если возможно, вообще не изменять его дизайн (например, создавать интерфейс, который содержал бы методы, которые я хочу смоделировать, и утверждать, что класс Customer реализует этот интерфейс, как правильно указал Хосе в своей статье). комментарий). То, что я попробовал, это второй вариант, упомянутый на финале конкурса . Несмотря на то, что это решило проблему, оно затормозило некоторые другие юнит-тесты :(, которые нельзя исправить ни одним очевидным способом.
Вопросов
Итак, вот два вопроса, которые у меня есть:
- Как это возможно в первую очередь? Разве тест не должен пройти как локально, так и в Дженкинсе?
- Как это можно исправить, основываясь на вышеупомянутых ограничениях?
Заранее благодарю за любую помощь.
источник
enable final
конфигурация работает в вашей рабочей области, но при запускеJenkins
не может найти этот файл. Проверьте, гдеJenkins
находится файл и находится ли он на самом деле там или нет.Customer
этом какая-то логика, или это просто тупой класс данных? Если это просто набор полей с геттерами и сеттерами, то вы можете просто создать его экземпляр.Ответы:
Альтернативный подход заключается в использовании шаблона «метод для класса».
Вот хороший блог на эту тему: https://simpleprogrammer.com/back-to-basics-mock-eliminating-patterns/
источник
Это, очевидно, своего рода env-специфика. Вопрос только в том, как определить причину различия.
Я бы посоветовал вам проверить
org.mockito.internal.util.MockUtil#typeMockabilityOf
метод и сравнить, чтоmockMaker
на самом деле используется в обеих средах и почему.Если
mockMaker
же - сравнить загруженные классыIDE-Client
VSJenkins-Client
- они не имеют никакой разницы по времени выполнения теста.Следующий код написан в предположении OpenJDK 12 и Mockito 2.28.2, но я считаю, что вы можете настроить его для любой фактически используемой версии.
С отдельным правилом для встроенных макетов:
источник
Убедитесь, что вы запускаете тест с теми же аргументами. Проверьте, соответствуют ли ваши настройки запуска intellij jenkins. https://www.jetbrains.com/help/idea/creating-and-editing-run-debug-configurations.html . Вы можете попытаться запустить тест на локальной машине с теми же аргументами, что и на jenkins (из терминала), если это не удастся, это означает, что проблема в аргументах
источник
org.mockito.plugins.MockMaker
существует также в машине Дженкинса. Я использую ту же JVM в бот-машинах. Я проверю 3, которые вы указали. Спасибо