dimanche 1 novembre 2020

Dependency injection with C. How run all the tests?

so I'm using [MinUnit][1] to run my tests with C.

This is the library:

 /* file: minunit.h */
 #define mu_assert(message, test) do { if (!(test)) return message; } while (0)
 #define mu_run_test(test) do { char *message = test(); tests_run++; \
                                if (message) return message; } while (0)
 extern int tests_run;

And this is an example of how I use it.

#include "minunit.h"
#include "function_under_test_source.c"
static char *test_ac1() {
    mu_assert("max char, should broke, it didn't",
              function_under_test() == 1);
    return 0;
}
static char *all_tests() {
    mu_run_test(test_ac1);
    return 0;
}
int main(int argc, char **argv) {
    char *result = all_tests();
    if (result != 0) {
        printf("%s\n", result);
    } else {
        printf("ALL TESTS PASSED\n");
    }
    printf("Tests run: %d\n", tests_run);

    return result != 0;
}

There is a little bit of boiler plate to write every time but it fits my purpose.

Now, to be able to abstract the testing from production code, I wanted to use dependency injection. For example if I want to test a function that uses getchar what I do is this:

int get_string(char s[], int maxChar, int (*getchar)()) {

so I pass the pointer to the actual function and then I mock it on the test like:

const char *mock_getchar_data_ptr;

char        mock_getchar() {
    return *mock_getchar_data_ptr++;
}

And then I use it in my test like this:

static char *test_ac2() {
    char text[100];
    mock_getchar_data_ptr = "\nhello!\n"; // the initial \n is there because I'm using scanf on production code (main.c)
    get_string(text, 100, mock_getchar);
    mu_assert("text is hello", strcmp(text, "hello!") == 0);
    return 0;
}

This is working but the problem is that I'm creating a C file for each unit test and then I'm compiling each test file and run the compiled version to test that it's working.

I of course can make a makefile but I was wondering if there is a more automatic orchestration for the tests.

Thanks [1]: http://www.jera.com/techinfo/jtns/jtn002.html

Aucun commentaire:

Enregistrer un commentaire