Задать вопрос
lina666
@lina666
Изучаю веб ЯП.

Почему компилятор не видит реализацию методов во компиляции?

Хочу написать юнит тесты для приложения, столкнулся с проблемой , уже не знаю куда тыкаться мб кто то подскажет в какую сторону копать

PlatformIO

platform.ini
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[common]
test_framework = unity
lib_deps =
    https://github.com/bblanchon/ArduinoJson@^7.4.0

build_unflags = -std=gnu++11
build_flags =
    -std=gnu++2a
    -Os
    -fdata-sections
    -ffunction-sections
    -fno-exceptions

monitor_speed = 115200
monitor_filters = 
    default
    time
    send_on_enter
monitor_echo = true

; ESP32 environment
[env:esp32s3]
platform = espressif32@6.10.0
board = esp32-s3-devkitc-1
framework = arduino
test_framework = ${common.test_framework}
lib_deps =
    ${common.lib_deps}
    https://github.com/ESP32Async/ESPAsyncWebServer@3.7.7
    https://github.com/mikalhart/TinyGPSPlus@^1.0.3 
    https://github.com/GyverLibs/GyverOLED@^1.6.4
    https://github.com/miguelbalboa/rfid@^1.4.12  
    https://github.com/FastLED/FastLED@^3.9.14
lib_ignore = 
    WebServer  ; Игнорируем библиотеку WebServer, так как она конфликтует с ESPAsyncWebServer

build_unflags = ${common.build_unflags}
build_flags =
    ${common.build_flags}
    -DBOARD_HAS_PSRAM
    -DPIO_ENV_ESP32S3

board_build.arduino.memory_type = qio_opi
board_build.filesystem = littlefs

monitor_speed = ${common.monitor_speed}
monitor_filters = ${common.monitor_filters}
monitor_echo = ${common.monitor_echo}

upload_speed = 921600
upload_protocol = esptool

; Desktop environment for testing
[env:desktop]
platform = native
test_framework = unity
build_flags =
    -DPIO_ENV_DESKTOP
    -Itest/desktop/mock

build_type = debug


Пытаюсь запустить тест
#include <unity.h>
#include "objects/User.hpp"
#include "structs/EffectZone.h"
#include "structs/GpsPosition.h"
#include "config.h"
#include <vector>

// Глобальные переменные для отслеживания колбэка смерти
bool deathCallbackCalled = false;
DeathReason lastDeathReason;

// Функция колбэка для смерти
void deathCallback(DeathReason reason) {
    deathCallbackCalled = true;
    lastDeathReason = reason;
}

// Сбросить состояние перед каждым тестом
void setUp(void) {
    deathCallbackCalled = false;
}

void tearDown(void) {
    // Здесь можно добавить код для очистки, если это необходимо
}

// Тест для проверки, что при нахождении в нескольких зонах одного типа применяется только самый сильный эффект
void test_only_strongest_zone_applies() {
    User user;
    GpsPosition position = { 50.0, 30.0 };
    user.updatePosition(position);
    user.setOnDeathCallback(deathCallback);
    
    // Создаем две радиационные зоны с разной силой урона
    EffectZone weakRadiationZone;
    weakRadiationZone.position = position;
    weakRadiationZone.radius = 10.0f;
    weakRadiationZone.type = TypeEffectZone::RADIATION;
    weakRadiationZone.damagePerSecond = MAX_RADIATION / 10.0f; // Слабая зона
    
    EffectZone strongRadiationZone;
    strongRadiationZone.position = position;
    strongRadiationZone.radius = 10.0f;
    strongRadiationZone.type = TypeEffectZone::RADIATION;
    strongRadiationZone.damagePerSecond = MAX_RADIATION / 3.0f; // Сильная зона
    
    // Создаем две пси-зоны с разной силой урона
    EffectZone weakPsiZone;
    weakPsiZone.position = position;
    weakPsiZone.radius = 10.0f;
    weakPsiZone.type = TypeEffectZone::PSI;
    weakPsiZone.damagePerSecond = MAX_PSI / 15.0f; // Слабая пси-зона
    
    EffectZone strongPsiZone;
    strongPsiZone.position = position;
    strongPsiZone.radius = 10.0f;
    strongPsiZone.type = TypeEffectZone::PSI;
    strongPsiZone.damagePerSecond = MAX_PSI / 4.0f; // Сильная пси-зона
    
    // Создаем вектор всех зон
    std::vector<EffectZone> zones = { weakRadiationZone, strongRadiationZone, weakPsiZone, strongPsiZone };
    
    // Время симуляции (радиация с DPS = MAX_RADIATION / 3.0f должна убить за примерно 3 секунды)
    unsigned long startTime = millis();
    unsigned long timeLimit = 5000; // 5 секунд - более чем достаточно для смерти от сильной зоны
    
    while (!deathCallbackCalled && (millis() - startTime < timeLimit)) {
        user.updateWithEffects(zones);
        delay(100); // Короткая задержка для симуляции
    }
    
    // Пользователь должен умереть от радиации раньше, так как сильная радиационная зона 
    // имеет более высокий DPS (MAX_RADIATION/3) по сравнению с сильной пси-зоной (MAX_PSI/4)
    TEST_ASSERT_TRUE(deathCallbackCalled);
    TEST_ASSERT_EQUAL(DeathReason::RADIATION, lastDeathReason);
}

// Дополнительный тест: убедимся, что если мы заменим сильную радиационную зону на еще более слабую,
// то смерть наступит от пси-излучения
void test_strongest_zone_applies_when_types_change() {
    setUp(); // Сбрасываем состояние
    
    User user;
    GpsPosition position = { 50.0, 30.0 };
    user.updatePosition(position);
    user.setOnDeathCallback(deathCallback);
    
    // Создаем две очень слабые радиационные зоны
    EffectZone veryWeakRadiationZone1;
    veryWeakRadiationZone1.position = position;
    veryWeakRadiationZone1.radius = 10.0f;
    veryWeakRadiationZone1.type = TypeEffectZone::RADIATION;
    veryWeakRadiationZone1.damagePerSecond = MAX_RADIATION / 20.0f; // Очень слабая зона
    
    EffectZone veryWeakRadiationZone2;
    veryWeakRadiationZone2.position = position;
    veryWeakRadiationZone2.radius = 10.0f;
    veryWeakRadiationZone2.type = TypeEffectZone::RADIATION;
    veryWeakRadiationZone2.damagePerSecond = MAX_RADIATION / 25.0f; // Еще слабее
    
    // Создаем сильную пси-зону
    EffectZone strongPsiZone;
    strongPsiZone.position = position;
    strongPsiZone.radius = 10.0f;
    strongPsiZone.type = TypeEffectZone::PSI;
    strongPsiZone.damagePerSecond = MAX_PSI / 4.0f; // Сильная пси-зона
    
    std::vector<EffectZone> zones = { veryWeakRadiationZone1, veryWeakRadiationZone2, strongPsiZone };
    
    unsigned long startTime = millis();
    unsigned long timeLimit = 6000; // 6 секунд - достаточно для смерти от пси
    
    while (!deathCallbackCalled && (millis() - startTime < timeLimit)) {
        user.updateWithEffects(zones);
        delay(100);
    }
    
    // В этом случае пользователь должен умереть от пси-излучения
    TEST_ASSERT_TRUE(deathCallbackCalled);
    TEST_ASSERT_EQUAL(DeathReason::PSI, lastDeathReason);
}

int main() {
    UNITY_BEGIN();
    
    RUN_TEST(test_only_strongest_zone_applies);
    RUN_TEST(test_strongest_zone_applies_when_types_change);
    
    return UNITY_END();
}


Выдает сначала кучу варнингов потом ошибку
Building...
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: .pio\build\desktop\test\desktop\test_user\user.test.o: in function `test_only_strongest_zone_applies()':
P:\stalker\dosimetr-arduino/test/desktop/test_user/user.test.cpp:31:(.text+0x104): undefined reference to `User::updatePosition(GpsPosition const&)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: P:\stalker\dosimetr-arduino/test/desktop/test_user/user.test.cpp:32:(.text+0x167): undefined reference to `User::setOnDeathCallback(std::function)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: P:\stalker\dosimetr-arduino/test/desktop/test_user/user.test.cpp:68:(.text+0x316): undefined reference to `User::updateWithEffects(std::vector > const&)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: .pio\build\desktop\test\desktop\test_user\user.test.o: in function `test_strongest_zone_applies_when_types_change()':
P:\stalker\dosimetr-arduino/test/desktop/test_user/user.test.cpp:85:(.text+0x474): undefined reference to `User::updatePosition(GpsPosition const&)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: P:\stalker\dosimetr-arduino/test/desktop/test_user/user.test.cpp:86:(.text+0x4d7): undefined reference to `User::setOnDeathCallback(std::function)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: P:\stalker\dosimetr-arduino/test/desktop/test_user/user.test.cpp:114:(.text+0x63a): undefined reference to `User::updateWithEffects(std::vector > const&)'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\desktop\program.exe] Error 1
Building stage has failed, see errors above. Use `pio test -vvv` option to enable verbose output.

и все, пробовал с флагом -v какой то дополнительной информации не увидел,
  • Вопрос задан
  • 9 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
ld.exe: .pio\build\desktop\test\desktop\test_user\user.test.o: in function `test_only_strongest_zone_applies()':
P:\stalker\dosimetr-arduino/test/desktop/test_user/user.test.cpp:31:(.text+0x104): undefined reference to `User::updatePosition(GpsPosition const&)'

Линковщик тебе говорит, что методы класса User не определены.

в какую сторону копать

Надо разобраться, где находятся реализации указанных функций, в objects/User.hpp или где-то ещё, и понять, каким образом должен собираться этот код.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы