[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [jfw] Re: Private methods should not be unit-tested



On 18 March 2014 14:10, Karthik Narendran <> wrote:
> Alright, rephrasing my question. How exactly does mocks help? Also what is
> the difference between mocks and test helper classes. Bit confused here.

Okay. Pull up a chair and get comfortable :)

So the test helper class is just a shortcut to access protected, and
sometimes private, properties and methods in a class. You can test
public methods easily by invoking them, for example:

$this->assertTrue($instance->publicMethod());

That's easy. However, it doesn't work for protected or private methods
and the helper is just there to save us writing the reflection code
all the time.

Now, mocking. The idea of mocking is to isolate the code you are
testing from code that you are interacting with. If you are, for
example, trying to test methods in an Application level class, it may
rely on database drivers and caching classes and a whole host of
dependencies. But to test a specific method in our application class,
we don't want to be using real database objects, etc. So we mock or
"simulate" their behaviour without actually running the the real code
in these dependencies. In Unit Testing, we are just worried about the
code in our particular class.

Let's imagine we have a class that uses a Cache object. In the repo
you'll see a Mock Helper class:
https://github.com/joomla-framework/cache/blob/master/Tests/Mocker.php
 PHPUnit has good support for mocking and the idea here is to create a
"fake" object to simulate the behaviour of calling `clear`, `exists`
etc and so on. In this way we can inject dummy data into a mock cache
object in order to test our specific class for different use cases
(when a value is in cache, when it's not, etc). We rely on the unit
tests in the Cache package itself to ensure that it works the way it
is intended to.

Here's an example where we "mock" a database object for testing the
AbstractDatabaseModel class
https://github.com/joomla-framework/model/blob/master/Tests/AbstractDatabaseModelTest.php

In that case we only want to test the code in that class and *not* run
the code in the real database class (we actually don't care about that
code at all, we just want to simulate it being used).

There's also the idea of "stubs" and the difference between them and
mocks is subtle. I would generally use a "stub" to test a abstract
class, because you can't instantiate an abstract class directly. That
may or may not be exactly what is meant by "stubbing", but it's how I
think about it. Here's an example of a stub:
https://github.com/joomla-framework/model/blob/master/Tests/Stubs/DatabaseModel.php

It's actually a concrete class whereas a mock is completely simulated.

But there is also integration testing where we do want to use all the
real object to ensure that, when combined, all the pieces actually do
work properly together. In that case, you don't use mocks.

It does, however, take some time to get your head around these
concepts, especially mocking. Even then, I look at tests I wrote years
ago and wonder if I was eating magic mushrooms at the time - some of
them are terrible and don't isolate the code well at all.

Does that help?

Regards,
Andrew Eddie

-- 
Framework source code: https://github.com/joomla/joomla-framework
Visit http://developer.joomla.org for more information about developing with Joomla!
--- 
You received this message because you are subscribed to the Google Groups "Joomla! Framework Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-framework+unsubscribe AT googlegroups.com.
Visit this group at http://groups.google.com/group/joomla-dev-framework.