C - Ignoring user inputs in CUnit?

270 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

4
Russell Reed 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.

0
Lars Ljung 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));
}