# Unit tests Framework: cmocka, accessed via `tests/prof_cmocka.h` (a thin compatibility wrapper). Run via `make check`. ## File layout - One test file per topic: `tests/unittests/test_.c` + matching `test_.h`. - Header declares each test function (one per `cmocka_unit_test*`). - Runner: `tests/unittests/unittests.c` — `#include`s every header, calls `cmocka_run_group_tests()` over a single big array. ## Registration Inside `unittests.c`, every test name appears in the array passed to `cmocka_run_group_tests`: ```c const struct CMUnitTest tests[] = { cmocka_unit_test(test_caps_show_basic), cmocka_unit_test_setup_teardown(test_join_room, muc_before_test, muc_after_test), // ... }; ``` Convenience macros are defined near the top, e.g.: ```c #define muc_unit_test(f) cmocka_unit_test_setup_teardown(f, muc_before_test, muc_after_test) ``` ## Test function shape ```c void test_account_set_jid_succeeds(void** state) { // Arrange will_return(connection_get_status, JABBER_CONNECTED); will_return(session_get_account_name, "alice@example.com"); ProfAccount* account = account_new("alice@example.com", ...); will_return(accounts_get_account, account); // Act gchar* args[] = { "set", "alice@example.com", "jid", "alice@example.org", NULL }; gboolean ok = cmd_account(NULL, CMD_ACCOUNT, args); // Assert assert_true(ok); } ``` ## cmocka primitives in heavy use | Primitive | When | |---|---| | `will_return(fn, value)` | Queue a return value for a stubbed function. Each call to the stub pops one. | | `will_return_count(fn, value, n)` | Queue the same value `n` times. | | `expect_string(fn, param, "...")` | Stub asserts that the named argument equals this string. | | `expect_value(fn, param, value)` | Stub asserts equality on a non-string. | | `expect_any(fn, param)` | Stub accepts any value (still pops the queue). | | `assert_true / assert_false / assert_string_equal / assert_int_equal` | Assertions inside the test. | | `cmocka_unit_test(fn)` | Plain registration. | | `cmocka_unit_test_setup_teardown(fn, setup, teardown)` | With per-test fixture. | `expect_*` queues are checked at test end — missing calls fail the test. ## Group setup / teardown For sets of tests sharing fixture: define a `_setup` and `_teardown` and register via `cmocka_unit_test_setup_teardown`. Examples in `unittests.c`: `muc_before_test`, `muc_after_test`, `keyhandlers_setup`, `keyhandlers_teardown`. ## What gets stubbed Tests run against the production `.c` files of the unit under test, with stubs replacing all dependencies. See `testing/stubs.md` for the layout. Standard idiom: every external function the unit calls must have a stub returning either a fixed value or a `will_return`-driven one. ## Running a single test `make check` runs everything. To narrow: ```sh ./tests/unittests/unittests --filter ``` (Confirm via `unittests --help`; cmocka filter support depends on version.) ## See also - `testing/stubs.md` — adding/extending stubs. - `playbooks/add-test.md` — adding a new test file end-to-end.