2016-08-31 26 views
6

Postaram się uczynić z tego czysto minimalny przykład, który będzie dotyczył tak wielu ludzi, jak to tylko możliwe, a także chronić jakikolwiek sposób dzielenia kodu, który mógłby naruszać NDA. Mam nadzieję, że to jest w porządku!CppUTest Unit Testing Framework Multiple Definition Exception

Używam CppUTest i CppUMock (kompilacja za pomocą gcc/g ++ i plików MakeFile utworzonych za pomocą CMake) w połączeniu z oprogramowaniem Gitlab Continuous Integration w celu utworzenia środowiska testowania jednostkowego dla przyszłych zatwierdzeń i wydania oprogramowania. Jednak natrafiłem na pewien problem. Załóżmy, że mam następującą konfigurację folderu (który mam minimalną zdolność do zmiany, inne niż zawartości folderu/testy):

+-- src 
    +-- driver1.c 
    +-- driver2.c 
+-- inc 
    +-- driver1.h 
    +-- driver2.h 
+-- tests 
    +-- test_driver1.cpp 
    +-- test_driver2.cpp 
    +-- main.cpp 
    +-- cmakelists.txt 

Plik CMakeLists będzie zawierać w tym folderu Inc, kompilację src folder i kompilacja folderu testów. Załóżmy jednak, że driver2.c opiera się na metodach określonych przez driver1.c. Jest to w porządku, jeśli nie ma opcji szyderstwa, ponieważ możesz po prostu przetestować wyniki wywołań metod sterownika2. Powiedzmy jednak, że chcę kpić z funkcji 1 metody driver1, dzięki czemu mogę sprawdzić, czy driver2 wywołuje metodę1 poprawnie (używając CppUMock). To zazwyczaj będzie w porządku, jeśli sterownik1 nie był kompilowany, ale dodając coś tak jak do pliku test_driver2.cpp:

void method1(int n) { 
    mock().actualCall("method1").withParameter("n", n); 
} 

spowoduje kolizji z rzeczywistą method1 w driver1.c z błędem łącznikową jak tak:

CMakeFiles/Tests.dir/.../src/driver1.c:(.text+0x11d): multiple definition of 'method1' 
CMakeFiles/Tests.dir/.../src/test_driver2.cpp:(.text+0x0): first defined here 

jak na wniosek komentującej, tutaj jest to, co to jest jak struktura:

driver1.c includes driver1.h (obviously) 
driver2.c includes driver2.h (obviously) 
driver2.h includes driver1.h (for calling method1) 
test cpp files include their respective .h files 
(test_driver1.cpp -> driver1.h and test_driver2.cpp -> driver2.h) 

method1 jest zadeklarowana w driver1.h i zdefiniowane w driver1.c. Nie mogę edytować tych plików.

Z przyjemnością dodam szczegóły zgodnie z życzeniem.

Jaki jest najlepszy sposób na obejście tego szyderczego problemu?

+0

Musisz pokazać (przynajmniej fragmenty) część, w której definiujesz metodę1 i jak #include różne nagłówki do źródeł – TemplateRex

+0

@ Dodano Dodano TemplateRex. method1 to po prostu jakakolwiek stara metoda w pliku driver1.c z deklaracją w pliku driver1.h. – Jeffrey

+0

nie można dodać kolejnego 'method1()' w driver2.cpp i połączyć go z driver2.cpp w sterowniku testowym. Jeśli chcesz udawać, powinieneś powiedzieć CMake, aby nie kompilował sterownika1.cpp jako zależności dla test_driver2.cpp – TemplateRex

Odpowiedz

3

Jeśli chcesz szydzić method1 od driver1.h, wystarczy dodać szydzili definicji w osobnym mock_driver1.cpp a następnie w CMakeLists.txt:

add_executable(target1 test_driver1.cpp driver1.cpp) 
add_executable(target2 test_driver2.cpp driver2.cpp mock_driver1.cpp) 

Gdy skończysz szyderczy, wymienić zależność mock_driver1.cpp z driver1.cpp.

To wszystko zakłada, że ​​masz oddzielny plik wykonywalny dla każdego sterownika testowego.

Jednakże, jeśli chcesz mieć jeden duży program główny, w którym wszystkie sterowniki są ze sobą połączone, nie można jednocześnie kojarzyć zarówno prawdziwego method1, jak i wyszydzanego method1. W tym celu, radziłbym zawijać wyśmiewany method1 w przestrzeni nazw mock lub coś podobnego, i tylko wywołać mock::test1 w test_driver2.cpp.

+0

Dzięki! Dodam, że mój skrypt budujący Pythona po prostu uruchamia wszystkie pliki wykonywalne w katalogu zamiast samego pliku tests.exe, dzięki czemu mogę mieć wiele kompilacji, takich jak wspomniany 2501. Wrócę z + 1-kami i zaakceptuję odpowiedzi, jeśli mogę uzyskać tę zmianę. – Jeffrey

+0

+1 Działa świetnie! To, czego mi brakowało, to po prostu posiadanie wielu jednostek kompilacji dla każdego testu, co jest znacznie łatwiejsze niż próbowanie zebrania ich wszystkich w jedno. – Jeffrey

+0

@Jeffrey wspaniale, że mogłem pomóc – TemplateRex

Powiązane problemy