noodlehaus/dispatch

move tests to PHPUnit

Closed this issue · 7 comments

need to use PHPUnit instead of adhoc tests. might need code changes as well, make things more testable.

heat commented

+1

+1

anyone has an idea how to test the whole redirect() functions with PHPUnit?

@dasrecht yeah, the problem with dispatch's redirect() and error() functions is that they have their own exit points. this is something i'm fixing in the upcoming version.

I've been playing with dispatch quite a bit and the lack of tests makes it really hard to know if I've broken something. (I can't even get the php 5.4 webserver tests to run at all - there's various curl and config problems).

It's tough to test a non-class implementation anyway, I couldn't find a way of using reflection to change the values of the static variables in various functions to reset after a test - there is a get method, but not set. (unlike for class variables with setValue) It would be very messy to have to add a reset parameter to all the functions that use statics!

What I think would work well though is using scope() to store all the statics for various functions (like content() uses it) and then give scope() a reset-all method like config() has. That gets the statics.

Next fix error() and redirect() so they have single return points and add a parameter to stop them exiting the script when in test mode.

The various trigger_error() calls can be tested by testing with custom error and exception handlers in the test suite to turn errors into exceptions so that the test cases can be wrapped in try { } catch { } and the error message+code examined.

The header() calls are hard to test. I think they all need making via a single send_header() function that can be switched into a test mode where the calling data is just captured and then in normal mode sent out with call_user_func_array('header',func_get_args()).

The file system access would probably be OK just to test live with real disk accesses. I looked at tricks for stubbing out global php functions, but they all involve either using Namespaces or quite involved server hacks ("runkit" etc.). That's a lot of work to test something that is supposed to be deliberately simple!

Just some thoughts :-) [I've tried all of these ideas and they work, but dispatch isn't mine to mess with!]

to test the things that involve headers, you'd have to have the xdebug extension. as for the use of superglobals, they can be unit tested but resetting the entire context on each run would be a pain.

an approach would be to move everything out into a class, then maintain the functions that we currently have now as a procedural facade, accessing the instance created on script load.

i'm not up for the task though, at the moment. would you be willing to give it a shot?

I already turned it into a quick&dirty class to be able to test some of the routing things that I have done, so that is almost there - it's not pretty, but it works. (I just moved all the statics out of functions into class variables and prefixed their names with the name of the function they belong to)

I could just tidy up what I have done slightly, write the facade functions and get it up as a repository for comment. If it looks OK in principle and hasn't spoiled the simplicity of the program then it could be refactored properly.

Try this: https://github.com/nmcgann/dispatch-class. I don't have a full application using Dispatch to test it with, so it would be great if someone else can beat it up and see if it behaves like the original.

I put a disclaimer in - it's not pretty code - proof-of-principle only!

I included some very crude "unit" tests with a very simple test class I borrowed from Fat Free Framework just to see if the various test issues could be fixed - exits/errors/headers etc. Looks good to me - PHPUnit should be able to do it properly.