0

I would like to test a method in my program, which handles shutdown of the application. At the end this method calls exit(0);

As expected this shuts also my test application down.

Is there a possibility to catch the exit signal in this particular unit test, so the shutdown of the test application can be avoided?

Simon
  • 1,616
  • 2
  • 17
  • 39
  • The better idea would be to end the program by returning from `main`. – user7860670 Mar 01 '18 at 10:29
  • @VTT Although I agree this is a legacy application and changing this would require serious refactoring. – Simon Mar 01 '18 at 10:31
  • You can use atexit() to call some function(s) on exit, but I doubt that it is possible to intercept exit() call (I mean, normally). BTW, why 'windows' tag? – freim Mar 01 '18 at 10:38
  • I don't mind a platform-independent solution, but the application currently runs under Windows only. – Simon Mar 01 '18 at 11:22

1 Answers1

1

Since there is no way to prevent exit() from ending the program, you will have to change the legacy application in some way or another.

For a similar problem I used the following solution:

  • A class that provides the feature I want to use/change through a public, static function, e.g.
    static void Wrapper::exit( int exit_code);
  • A base class that declares the interface of the features I want to provide:
    virtual void Base::exit( int exit_code) = 0;
  • Then a class, derived from the base class Base, that implements the normal behaviour:
    void OsImpl::exit( int exit_code) { ::exit( exit_code); }
  • The Wrapper class finally contains a pointer to the implementation to use, by default an object of OsImpl, but that can be replaced by e.g. a TestImpl that does nothing.
    static void Wrapper::setImpl( Base* handler);
  • Finally, in the application replace ::exit( 0); by Wrapper::exit( 0);
    When run "normally", the application will stop as before, but in your test program you can make it return to the test function.

I know this is quite condensed, but I hope you get the idea.

Rene
  • 2,466
  • 1
  • 12
  • 18
  • I like the idea – Simon Mar 01 '18 at 13:13
  • I ended up just making a test subclass of my class under test and excluding the exit call, because this approach would lead to a stack overflow exception at shutdown. But I will use this approach for similar problems. – Simon Mar 02 '18 at 13:44
  • 1
    Well, you have to make sure that OsImpl::exit() calls ::exit() and not itself again ... The easiest way to achive that is to use namespaces and/or different function names. – Rene Mar 02 '18 at 14:09
  • You're right, I missed the '::'. Was obviously too late yesterday evening ;-) – Simon Mar 02 '18 at 14:24
  • So I reworked it again to your solution and this time I used `::exit()` and it works like a charm. Thanks again! – Simon Mar 12 '18 at 08:09