问题
I am trying to use Google Test to test C code but I am encounter some problem related to write stub for system functions like: fopen,fclose,fread,fwrite, memcpy,memset,stat,...I don't known how to stub them correctly to cover all branchs in function that need to be tested.
Example , I have a function, how to test it by stub fopen, fclose, fwrite, fread? Only Stub, not Mock.
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *f;
//initialize the arr1 with values
int arr1[5]={1,2,3,4,5};
int arr2[5];
int i=0;
//open the file for write operation
if((f=fopen("includehelp.txt","w"))==NULL){
//if the file does not exist print the string
printf("Cannot open the file...");
exit(1);
}
//write the values on the file
if((fwrite(arr1,sizeof(int),5,f))!=5){
printf("File write error....\n");
}
//close the file
fclose(f);
//open the file for read operation
if((f=fopen("includehelp.txt","r"))==NULL){
//if the file does not exist print the string
printf("Cannot open the file...");
exit(1);
}
//read the values from the file and store it into the array
if((fread(arr2,sizeof(int),5,f))!=5){
printf("File write error....\n");
}
fclose(f);
printf("The array content is-\n");
for(i=0;i<5;i++){
printf("%d\n",arr2[i]);
}
return 0;
}
回答1:
Your file()
function in sample.c
calls fopen()
. Defining fopen
as something else in a totally different file (compilation unit) is not going to change that.
You cannot simply mock a free function.
You can change the file()
function to take a pointer to the fopen()
function to use. In your tests you then provide a pointer to your mock function when calling the file()
function. This is a form of dependency injection.
Another option is to use conditional compilation.
An example of using dependency injection:
// Typedef for our "fopen interface". Makes our code a bit more readable.
typedef FILE *(*fopen_type)(const char *, const char *);
FILE *file(fopen_type fopen_func)
{
FILE *f = fopen_func("abc", "r"); // Call the provided "fopen" function.
return f; // Let's return the opened file or `NULL`.
}
And then in your test code:
TEST(OPEN_FILE, OK)
{
ASSERT_NE(NULL, file(&my_fopen));
}
If you use many system functions that you want to mock, you can also create a struct that contains pointers to all the relevant functions.
struct system_calls {
fopen_type fopen;
// Add more system calls here.
};
FILE *file(struct system_calls *p)
{
FILE *f = p->fopen("abc", "r");
return f;
}
The premise here is that if you want to test your code, you need to write testable code. Dependency injection is one way to achieve that.
来源:https://stackoverflow.com/questions/59394613/stub-system-function-in-google-test