Я работаю над автоматическим модулем и интеграционными тестами для робота. Как вы могли догадаться, у робота много сенсорных объектов, и такие, которые должны были бы использоваться во время тестирования.
Одной из зависимостей является синглтон, созданный не для создания чего-либо, кроме самого себя. Как я понял (я новичок в JMockit), когда класс аннотируется @Mocked
, все его методы и конструкторы подвергаются насмешкам. Документация JMockit :
Существуют три разные аннотации-насмешки, которые мы можем использовать при объявлении фиктивных полей и параметров: @Mocked, который будет насмехаться над всеми методами и конструкторами на всех существующих и будущих экземплярах макетируемого класса
Однако я заметил (с помощью точки останова), что конструктор реального класса вызывается и не может получить доступ к датчику, что приводит к сбою тестов.
Вот соответствующая часть синглтона, который я пытаюсь высмеять. Обратите внимание, что я не могу изменить этот класс:
public class DriverStation() {
// This line in particular is an issue.
private static DriverStation currentInstance = new DriverStation();
public static DriverStation getInstance() {
return DriverStation.instance;
}
private DriverStation() {
// This constructor cannot be called during tests.
}
}
А вот мой тестовый код:
public class BlingControllerTest {
@Mocked
private DriverStation station;
@Tested
private BlingController blingController;
/**
* Tests getting the robot's operation period while not in a real match.
*/
@Test
public void testGetOperationPeriodDuringRealMatch(@Mocked DriverStation station) {
new Expectations(DriverStation.class) {{
DriverStation.getInstance();
result = station;
station.isFMSAttached();
result = true;
station.isAutonomous();
returns(true, false);
}};
}
}
Полный исходный код также доступен на GitHub
Я должен также упомянуть, что по какой-то причине локальный вызов конструктора синглтона во время тестов не является проблемой, но когда тесты выполняются на travis-ci, это проблема.
Stacktrace от запуска на travis-ci:
ca.team2706.frc.robot.commands.bling.BlingControllerTest > testGetOperationPeriodDuringRealMatch STANDARD_ERROR
java.io.IOException: wpiHaljni could not be loaded from path or an embedded resource.
attempted to load for platform /linux/x86-64/
at edu.wpi.first.wpiutil.RuntimeLoader.loadLibrary(RuntimeLoader.java:79)
at edu.wpi.first.hal.JNIWrapper.<clinit>(JNIWrapper.java:25)
at edu.wpi.first.wpilibj.DriverStation.<init>(DriverStation.java:194)
at edu.wpi.first.wpilibj.DriverStation.<clinit>(DriverStation.java:132)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at mockit.internal.state.TestRun.ensureThatClassIsInitialized(TestRun.java:138)
at mockit.internal.expectations.mocking.BaseTypeRedefinition.redefineType(BaseTypeRedefinition.java:65)
at mockit.internal.expectations.mocking.TypeRedefinition.redefineType(TypeRedefinition.java:28)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldType(FieldTypeRedefinitions.java:78)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldType(FieldTypeRedefinitions.java:65)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.redefineFieldTypes(FieldTypeRedefinitions.java:53)
at mockit.internal.expectations.mocking.FieldTypeRedefinitions.<init>(FieldTypeRedefinitions.java:33)
at mockit.integration.TestRunnerDecorator.handleMockFieldsForWholeTestClass(TestRunnerDecorator.java:142)
at mockit.integration.TestRunnerDecorator.updateTestClassState(TestRunnerDecorator.java:40)
Любая помощь приветствуется.