22 Jun 2014, 01:24
Generic-user-small

Richard Hagberg (10 posts)

Hello all,

I am currently using Visual Studio 2013 to learn TDD. It is most likely going to be the enviroment I am going to use to test with. I am having trouble using Link-Time substition. In apendix A1.2 of Test Driven Development for embedded C, James talks about how the make file creates the production code library first, then creates the test object (.o) files next, and when the compiler links them it uses the symbols from the object files to resolve unresolved symbols first. In using Visual Studio, I have tried creating a library file from the production code, including that .lib file in the tests project and compiling. Even with separating the two projects like this, it still gives me an error saying that the function is already defined.

I am just wondering if anyone knows of how to do this in Visual Studio without using a makefile? I have never used a make file before, and would rather not try to learn another tool while still getting the hang of TDD. Is it possible at all? If not, does anyone have any suggestions on a quick way to understand makefiles? I have tried to use things like cmake, but I guess they are assuming I know something I don’t because I still feel lost.

I feel that this sort of thing should be totally doable in Visual Studio, but for the life of me, I can’t figure out how. Thank you in advance.

22 Jun 2014, 06:04
Generic-user-small

Richard Hagberg (10 posts)

One thing I just discovered is that if your spy or mock or whatever includes a function to stand in for each of the functions in the production code file, then the solution will compile. So if your IO.c has an IO_Read and an IO_Write, then your IO_Spy.c file must also have IO_Read and IO_Write. If it only has and IO_Read, then you will get the multiplicity error. This is true in VS2008 as well as VS2013. So you can use link-time substitution in Visual Studio 2008/2013, but you need to work on stand in functions for all of the functions in your production code file before you compile. During normal TDD this shouldn’t be much of a problem, but it could make things difficult if you are writing tests for legacy code. I am going to continue to play around with it and will post anything I find. If anyone else knows how this can be done in an easier or better way, your help would be much appreciated.

23 Jun 2014, 19:18
Generic-user-small

Richard Hagberg (10 posts)

So in doing a little more playing around I have come to discover that the reason I had to create stubs for each function in the file I was testing with is because the other two fucntions called the third. so let’s say that my functions were named A, B, and C respectively. I was creating a mock of C to test out CppUMock with. The problem was that A and B also called C, so when I tried to replace C with a mock, A and B had already been compiled into a library using the original function C, so the linker was trying to include both in the .exe. That is why I had to create stubs for A and B in order to get rid of the error. The Linker was then just replacing the whole module. when I added a function D to the same library file and didn’t refrence it from A, B, or C, I didn’t get the error. This led me to the realization of what I was doing wrong. I think I am slowly getting the hang of TDD and mocking in Visual Studio. If anyone has any questions or would like to share any insights I would more than welcome a comment here.

02 Jul 2014, 12:16
Generic-user-small

Arnd R.Strube (57 posts)

For complex stubbing situations (e.g. within one C source file, I want to keep some of the original functions, use dummies for others and also throw in a mock or two, my approach is to stub all function by fakes that delegate the call via function pointers. I then set the pointers in my test case as needed.

I guess you might call this runtime substitution ;-). It carries some overhead, but is extremely flexible.

I have an example of how to do this at github.com/arstrube/FakeFunctions.

02 Jul 2014, 12:09
Generic-user-small

Arnd R.Strube (57 posts)

Hi Richard,

Linktime substitution does not depend on a makefile. Most IDEs (VS included) offer a way to specify which source files should be included in a given build.

Generally, the thing to do is to exclude the original code, and to include the faked code.

Of course, this can only be done on a per-source-file basis (same as with a makefile). See my previous post if you need finer granularity – this is however no longer link-time substitution but run-time substition.

28 Aug 2014, 02:48
James2009_pragsmall

James Grenning (141 posts)

Linker substitution has its limitations. In the book I run into this problem in the Refactoring chapter, section called Move Function.

Like you guys have already discussed, when A, B and C are all in the same compilation unit, and you only want to stub C, you have to split the file. I don’t mind doing this usually because this usually leads to a better design and separation of concerns.

  You must be logged in to comment