问题
I'm reading "Test-Driven Development for Embedded C," by James W. Grenning.
I'd like to reproduce case with "Link-Time Substitution" using Visual Studio Community 2019 and gTest.
I have the following code:
production_code staticly linked library
foo.cpp
#include "foo.h"
int foo(int x) {
return x + 1;
}
foo.h
#ifndef _foo_
#define _foo_
int foo(int x);
#endif //_foo_
In gtest project production_code library is included via reference test.cpp
#include "gtest\gtest.h"
#include "gmock\gmock.h"
#include "..\prod\foo.h"
//fake implementation of production code foo
int foo(int x) {
return x - 1;
}
TEST(TestCaseName, TestName) {
auto x = foo(5);
EXPECT_EQ(x, 4);
}
The linker gives me following error:
1>prod.lib(foo.obj) : error LNK2005: "int __cdecl foo(int)" (?foo@@YAHH@Z) already defined in test.obj 1>C:\Example\prod_test.exe : fatal error LNK1169: one or more multiply defined symbols found
What have I missed here? Why doesn't this work?
If I add the command "/FORCE:MULTIPLE" to linker, then I get only warning, but I think that this is not the right approach to doing this.
回答1:
This situation occurs because you defined foo(int)
in 2 places: foo.cpp and test.cpp and you build your code with this files. If you need to run some test with a stub (fake function foo(int)
in this case) you need to create 2 targets of build for:
- building of your real application
- building of a special application for unit testing (and than run it)
And when you build the application for unit testing, you link it with test.cpp (but not with foo.cpp). Also when you build your real application you link it with foo.cpp (but not with test.cpp).
Note: it's make sense to test real code and create a stub when this stub provides some additional functionality according to idea of a test (for example, you check your sort()
function but you can use stub to generate data for sort()
because the data are provided after some complex algorithm finished working and the computing takes a lot of time) or you don't want to use some resources (for example, you check your sort()
function but you use a network connection to a server to get real data for sort()
) or you need to provide some specific data for testing you algorithm (for example, to check a corner case using specific data; or maybe you have found the sort()
doesn't work with specific data). But again, it's make sense to test real code.
来源:https://stackoverflow.com/questions/58484081/c-unittest-with-linktime-substitution