C - Ignoring user inputs in CUnit?

259 Views Asked by At

I've been search around for an answer but I haven't found one. The thing is, I need to do some test cases for a program I've written in C. The thing is, some functions take in an user input which makes my test cases to wait for an input, which is not what I want.

This is one of my test cases:

void test_is_location_free() {
  Storage test_storage = new_storage();
  Item test_item;
  test_storage->inventory[5] = test_item;
  test_storage->inventory[5].loc.shelf = 'A';
  test_storage->inventory[5].loc.place = 1;

  CU_ASSERT(!is_location_free(test_storage, test_item, 'A', 1));
}

This works because is_location_free() will return false, but inside the function I have another function that will keep asking the user for a new input, until the selected location is free.

This is how it looks in the terminal, where it will wait for a new user input for the shelf:

Suite: HELPER FUNCTIONS
  Test: compare_char() ...passed
  Test: first_empty_position() ...passed
  Test: is_location_free() ...Location not empty, try again!
Shelf:

Is there any way to ignore all user inputs in total, or maybe define a future user input that my test case will use?

Thanks!

2

There are 2 best solutions below

0
On

You can easily write your own version of fgets() for your unit tests. This is called mocking and is very common in unit testing. Something like this should work:

static char test_input[MAX_INPUT];

char *fgets(char *s, int size, FILE *stream)
{
  strncpy(s, test_input, size);

  return s;
}

Then rewrite your test like this:

void test_is_location_free() {
  Storage test_storage = new_storage();
  Item test_item;
  test_storage->inventory[5] = test_item;
  test_storage->inventory[5].loc.shelf = 'A';
  test_storage->inventory[5].loc.place = 1;

  strncpy(test_input, "test input data", MAX_INPUT);

  CU_ASSERT(!is_location_free(test_storage, test_item, 'A', 1));
}
4
On

Assuming that your code is getting the user input from the standard input stream, you could write the data to a file and temporarily change standard input to read from that file before calling the is_location_free function.

I think the same idea could work if user input is being read from the terminal instead (/dev/tty), but would require more effort.

Note: In this particular case, I would recommend just refactoring your code so that the is_location_free function only does what it's name suggests. Then it would be easy to test. Write a second function to add the behavior where you prompt the user if the first location didn't work. You might choose not to have CUnit tests for that second function.