Unit Test Abuses — Who Needs Mocks?

So, when I fix a bug, I like to wrap a test around it to catch regressions. When I wrote the test for the bug discussed under Debugging adventures with DBD::Sybase, I had to make an unusual work-around…

eval {
    # ick. ick. ick. You didn't see me do this.
    no warnings 'redefine';
    local *App::is_schedule_found = sub { pass("called bogus func");  return (1, 'ok'); };
    ($ok, $msg) = App::process_row($dbh, $questionable_row);
    ok($ok, "processing row: $msg");
unlike($@, qr/^Panic: Can't have multiple statement handles on a single database handle when AutoCommit is OFF/,
        "Sybase Error Handling busted");

I’ve changed the package name to “App” to protect the guilty. process_row calls is_schedule_found, and bails out if it’s not found. Since this bug only show up when testing against the real database, I can’t fake out the data source. So I insert the appropriate prerequisite data, and then run the procedure. But I don’t want to build up the whole structure just to adjust one table. (The database doesn’t have integrity constraints… Not my preference, but that’s how it is today.)

So I replace the function that checks for the schedule with one that always returns true. I don’t need to dependency inject a mock with an interface, I just adjust the global symbol table.

Comments are closed.