2011-12-06 14 views
6

Bardzo podobają mi się funkcje łącznika GNU, aby znacznie zawijać funkcje. Zwykle używam tego fałszywego, np. niedeterministyczne wywołania funkcji, takie jak rand(). Rozważmy następujący przykład, w którym chciałbym napisać badanej jednostki dla giveMeANumber:Zawijanie funkcji C++ za pomocą łącznika GNU

//number.cpp 
int giveMeANumber() { 
    return rand() % 6 + 1; 
} 

mogę zawinąć wywołanie rand z GNU funkcji łącznika owinąć jak ten:

//test.cpp 
extern "C" int __wrap_rand(void) { 
return 4; 
} 

void unitTest() { 
    assert giveMeANumber() == 5; 
} 

$ g++ test.cpp -o test number.o -Xlinker --wrap=rand 

Czy istnieje jakiś sposób, zrobić to samo z normalnymi funkcjami C++? Następujące nie działa, myślę, że to z powodu manglingu nazwy. Ale nawet kiedy próbuję tego z zawikłaną nazwą, to nie działa.

//number.cpp 
int foo() { 
    //some complex calculations I would like to mock 
} 
int giveMeANumber() { 
    return foo() % 6 + 1; 
} 

//test.cpp 
extern "C" int __wrap_foo(void) { 
return 4; 
} 

$ g++ test.cpp -o test number.o -Xlinker --wrap=foo 

Jakieś pomysły?

+0

W rzeczywistości rand jest funkcją deterministyczną. Zwraca sekwencję liczb pseudolosowych. Wywołania randu zwrócą tę samą sekwencję liczb dla dowolnego materiału siewnego użytego w srand. – TJD

+1

Okay, bravo, to prawda. Ale żeby przykład był krótki i czytelny, nie użyłem nasion. – Mike

+0

Musisz zmienić nazwę '__wrap_foo' na' getRandomNumber'. (http://xkcd.com/221/) –

Odpowiedz

8

Trzeba albo też extern "C" funkcja chcesz zawinąć (jeśli to możliwe) lub trzeba owinąć zniekształconej nazwy, np __wrap__Z3foov a następnie przekazać --wrap=_Z3foov do łącznika.

Prawidłowe podkreślenie jest trochę skomplikowane. To działa dla mnie:

$ cat x.cc 
#include <iostream> 
using namespace std; 

int giveMeANumber(); 

int main() { 
    cerr << giveMeANumber() << endl; 
    return 0; 
} 

$ cat y.cc 
int giveMeANumber() { 
    return 0; 
} 

extern "C" int __wrap__Z13giveMeANumberv() { 
    return 10; 
} 

$ g++ -c x.cc y.cc && g++ x.o y.o -Wl,--wrap=_Z13giveMeANumberv && ./a.out 
10 
+0

C powiązanie do zawijania Funkcja C++ nie jest opcją, ponieważ ta funkcja może być przeciążona i nadal powinno być możliwe wywoływanie jej z innych funkcji C++. Próbowałem zawinąć zmasakrowane imię, ale to nie działa. To, co zrobiłem, to: "extern" C "int __wrap__Z3foov (void) { \t return 4; } void thisIsATest() { assert 5 == giveMeANumber(); } 'wraz z opcją linkera' -Xlinker --wrap = _Z3foov'. Niestety, wciąż wywoływana jest prawdziwa funkcja 'foo'. Jakieś pomysły? – Mike

+0

Dodałem przykład. Zajęło mi trochę czasu, aby uzyskać wszystkie podkreślenia. – smparkes

+0

Dziękuję za pytanie. Nawet nie wiedziałem o --wrap. Bardzo dobrze. – smparkes

1

Wygląda na to, że próbujesz kpić z funkcji i klas do testowania. Czy należy rozważyć użycie Google Mock

+1

Używanie makiety Google nie jest dla mnie opcją. Chcę to osiągnąć wyłącznie za pomocą łącznika GNU. – Mike

Powiązane problemy