Why bother with PHPUnit?

DrDamnit used Ask the Experts™
Loaded question, I know. But, we recently started to implement PHPUnit with our new projects, and while it's neat to write the tests, they ALWAYS pass because I am testing how objects are instantiated or used in a vacuum. I am sure this is not the sum total of PHPUnit's abilities, and perhaps my answer is using mock objects. But, what I really want to test with PHPUnit is "What happens when a user violates the norms during the course of use? What will break?" i.e., what happens when a user acts like... a user?

Of course I need to ensure that when we instantiate a class of "Customer" the getBalance() method returns a number not null, and not a string. But there has to be more to it than that.

Can anyone give a short narrative on how they use PHPUnit to test more than: "Is this class written properly"?
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2017
Distinguished Expert 2018

Well the obvious answer is to write tests to pass in different user inputs both valid and invalid and test that the code handles those correctly

1. The output is correct
2. Bad data does not cause a program crash or unpredictable results

Unit tests are useful when your code base starts to get large - you want to make sure that additions to code don't result in side effects that cause other parts of the application to break.

To fully get to grips with unit testing you should be up to speed with Dependency Injection - instantiating objects and then passing in dependencies either as parameters to the constructor or through setter methods or by means of a factory.

This way you can inject "bad" data to test how the application deals with it. You can also create test dependency objects and inject those in to see how the code behaves under different conditions.

The bigger and more complex the code base and the bigger the development team the more unit testing pays off and makes sense.
Most Valuable Expert 2012


Everything we code is an object. We use dependency injection as a strict requirement. We use factories and polymorphism where ever it can replace if statements.

Where I am mentally falling short is: should I be using mock objects to intentionally create bad data?
Most Valuable Expert 2017
Distinguished Expert 2018

Where I am mentally falling short is: should I be using mock objects to intentionally create bad data?
That's part of it - one of the benefits of DI is that you can pass in "bad" objects (within reason) to test how the code responds to the input. Obviously this must be done within the context of how the software will be used i.e. input is limited to what the user / program can create / input.

Simplistic example - add to balance

Submit a number - expect result to be current balance + number
Submit a string - expect an error and current balance is unchanged.

This is over simplifying the problem - depending on how you have structured your code it may be that data is validated and sanitised before it gets to the object - so additional checks within the object may be superfluous.

The key point is that you use the unit tests to rapidly run a series of checks to make sure the key parts of your application are doing what they should be doing after a change to the code base.
Most Valuable Expert 2011
Top Expert 2016
perhaps my answer is using mock objects
Yes, that is a big part of the answer.  The point of TDD is to automate the production of tests - some at the center, some at the edges and some at the corners.  With a good collection of tests you can be fairly certain that your new code (refactored code) did not cause a regression of a previously tested assertion.

Rough outline from the olden days here:

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial