Mocking Objects for Unit Testing in PHP Using Go! AOP

These have been always very important questions in software development industry; what should I test in unit testing? And how can I make tests as small as possible, and how to avoid testing already tested code? or 3rd party libraries?

In fact, there are many approaches, but almost all of them agree that, you don’t have to test everything, and that, you have to mock some methods/objects those which you don’t own (for example, 3rd party libraries/code, or another example could be your own tested code). In principle, unit test must fail for one and ONLY ONE reason, this makes sense actually, as it complies with the S in the SOLID object-oriented design principles, which makes the following test, for example, a bad test as it stands:

And here is the bad test …

The test in PostTest::testCreatePost is bad unit test for many reasons, most importantly, it may fail for more than one reason. For example, getting the user by ID getUser in Post::createPost() may fail for some reason, then the testCreatePost will fail, for a reason that is not related to the name of the test. In other words, testCreatePost must only fail if the creating a post failed, not because of anything else, like failure to get user from DB. Second reason why this is a bad unit test, is that, there will be many DB calls, and that is not cheap resource to use in the test.

How to Make It Good Unit Test

The solution here that makes most sense is to use Mock Objects. What is a mock object? According to Wikipedia:

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways.

In other words, in some cases, we need to just return some already prepared values instead of calculating the real values, because the real value maybe very complex to calculate or takes too long time to be calculated or may take a lot of resources.

How This Applies To Our Problem

We can use mocks in the problem listed above, to make the unit test, real unit test, that is testing only the things that needs to be tested. To do this there are many good libraries for all the programming languages, for example Mockery for PHP, Mockito for Java, and many other libraries.

However, what we are going to do today is something different. OK! Why should we re-invent the wheel? the answer is : because it is simpler wheel ! also it is a wheel that uses different technology which is AOP.

In this blog post I will use mainly Laravel 4.2 with the Go! AOP Framework by Alexander Lisachenko, which is the framework that I use in my work (For caching, monitoring, security, and mocking), and it showed very high efficiency.

Step-by-Step Manual

You can find all the codes listed in this step-by-step manual in this GitHub repository.

First things first, we need to add the required libraries to the composer.json file. The require part of the composer file should look like:

The following was added:

  • MongoDB support to Laravel (Jenssengers), since the DB that I am using for this example is MongoDB.
  • Go AOP framework, which is the AOP support in this project.
  • Finally, I added the PHPUnit framework dependency to gain the advantage of auto-complete in my IDE when I am changing the unit test cases.

Then after adding these dependencies to your composer.json, you need to run composer update command in the root directory of your project.

Start Using Go AOP

The core of our mocking mechanism is the AOP provided by the Go AOP framework. So after adding the dependency to your project, you have to configure the project to use the AOP library, everything you need is written here (Thanks to Alexander Lisachenko 🙂 ).

In the configuration used in this project, ApplicationAspectKernel.php was put inside app/aspect directory, along with the cache directory and our main and only aspect the MockAspect.php. For bootstrapping the AOP framework, the bootstrap/autoload.php was used as follows:

Now, everything is set, and can be used. So we start writing actual code. First, we add a config file app/config/aopmock.php and app/config/testing/aopmock.php, these two files, will be used to check for two things: first, whether the environment where the application is running is testing or production environment, second, whether the method being invoked now is a method that must be mocked or not. Both of these two checks will be done in MockAspect.php , which is the core of our work (its code is listed below).

In the MockAspect class, there are two interceptors, one of them is intercepting static methods, the other is intercepting the dynamic ones. However, both of them are intercepting any methods invocations that happen in any namespace, in any file located inside app directory or any of its subdirectory.

What happens when it intercepts a method invocation is the following:

  • Checks if the method is mockable
  • … and return the mocks if it is, or proceed with the invocation otherwise.

To do this, basically the interceptors call MockingAspect::isMockable() which checks for the current runtime environment, and returns null if it is not testing environment. Then, it checks if the method invocation is being done on a class and a method that was listed in the aopmock.php or was added to the file by the AopMocker class in the runtime.

The AopMocker class is a utility helper class, that will be used to mock methods by adding them to the configuration file aopmock.php in the runtime. This class is the interface to the mocking mechanism, and here is its code:

Improve Our Unit Test

Now, it is time to improve our unit test listed above. As we said, we have to use mocks. So all we need to do is just mock the enormous, and very expensive operations as follows:

What we did is very simple, we just told the application that from now on, in the unit test, don’t execute the actual User::getUser() method, just return the sample user right away, same goes for Post->save(), the save will be considered done successfully and return true always. This is now a unit test, that is only testing one task, that will fail only for business logic related issues in creating post, like passing an empty title for example. One last thing needs to be mentioned here, is that the Post model will be using the MockableModel trait.

That is because, Go AOP cannot intercept the inherited methods if they are not in the directory specified in the initial configuration. So we put all the methods that are inherited from classes outside the AOP directory, but we want them to be intercepted and mocked in the MockableModel trait, in our case the save() and delete() of the Jenssegers/Mongodb/model.php.

Possible Future Improvements

It is possible to use Annotations instead of config files to intercept methods that needs to be mocked, just like in the caching example introduced by Alexander Lisachenko in his article title Caching Like A Pro where he, used @cacheable annotation on the methods that must be cached. Similarly we can create an annotation called @mockable to intercept methods that must be mocked in testing environment.

Maybe we talk about this in another post. For now enjoy AOP using Go! Framework, and enjoy unit testing, proper unit testing 🙂

Don’t forget to check the GitHub Repo for the complete project.

Thanks for reading 🙂

How To Implement Scroll Listener In Vaadin 7 Tables

In Vaadin, when you scroll down or up in tables (com.vaadin.ui.Table) there is no event that will be fired to tell you that user is now scrolling.

Why would we need scroll event in table?

Let’s first take a look at this example of Vaadin (Dashboard Demo) after you open the link just click sign in, and you’ll be automatically redirected to the transactions page, this page shows a table of financial transactions, these transactions will show a batch after another while you are scrolling, what actually happened is that the data was loaded on UI initiation (all the transactions).

Now, let’s assume that we have thousands or say millions of transactions. Is it logic to load them all together when the UI is initiated? isn’t it of wisdom to load them bit by bit to prevent slowing down the UI while it waits for all transactions to load?.

The best solution to this problem is to get the first (say 100 transactions) then get more transactions while scrolling down, but this solution have only one problem, that is Vaadin does not support Scroll Event Handling in com.vaadin.ui.Table !! Yes, but that’s only the bad news, the good news is that we have a solution to work this out.

Vaadin Table’s Scrolling Event

The Dashboard Demo (GitHub repo) project actually depends on Vaadin tables as you see in the code in this file in line 53, what we are going to do is to extend com.vaadin.ui.Table and implement our own behavior that will support scrolling Vaadin tables from now on.

First of all, let’s create new simple interface ScrollingTableScrollListener this interface will be responsible for implementing scroll events and its code will look like this:

package com.vaadin.demo.dashboard.scrolling;

public interface ScrollingTableScrollListener {
     public void doTableScroll();
}

This interface should be implemented whenever you have a table in your view and you want to add a scroll event handler for it. But wait a minute this is not applicable to any kind of tables, this is only applicable to our own table.

Now, let’s create our table, our table’s name is  (ScrollingTable) and it extends (com.vaadin.ui.Table) this class code is:

package com.vaadin.demo.dashboard.scrolling;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.vaadin.ui.Table;

public class ScrollingTable extends Table {

	private static final long serialVersionUID = 5007124121625961567L;
	List listeners = new ArrayList();

	private void fireSrollEvent() {
		for (ScrollingTableScrollListener listener : listeners) {
			listener.doTableScroll();
		}
	}

	public void addScrollListener(ScrollingTableScrollListener listener) {
        listeners.add(listener);
    }

	@Override
	public void changeVariables(Object source, Map variables) {
		super.changeVariables(source, variables);
		fireSrollEvent();
	}
}

Actually, this table is the same as Vaadin’s one, but it has the following differences:

  1. It overrides the method changeVariables() of the super class (Vaadin Table : com.vaadin.ui.Table), actually here lays our core business that will initiate the Scrolling Behavior. What we did here is that we invoked the changeVariables() of the super class and then we invoked the fireSrollEvent() method.
  2. Another difference is that it has two more members:
    1. public void addScrollListener(ScrollingTableScrollListener listener) this method will take care of adding new listeners to table’s scrolling event.
    2. private void fireSrollEvent() this method is the one that will be invoked by changeVariables() method and will invoke the method doTableScroll() on every registered listener that this table has added by invoking the method addScrollListener().

Now to make use of the new stuff that we have added, we will change the original code of the aforementioned Dashboard demo (specifically the file TransactionsView.java). In this file there are only few lines to add and modify.

First, we will modify the line 49 by adding new interface that this class will implement, which is our new interface (ScrollingTableScrollListener) and implement its single method by adding the following lines in the end of this class:

@Override
public void doTableScroll() {
	// TODO Auto-generated method stub
	Notification.show("You are scrolling!\nYou can add your own behavior here!");
}

Then, we will change both lines 53 and 66 to use the new inherited class (ScrollingTable) rather than the super class (Table):

//Line 53 in the original class
Table t;
//Line 55 in our class
ScrollingTable t;
....
....
....
//line 66 in the original class
t = new Table() {
//line 68 in our class
t = new ScrollingTable() {

Finally, we should add the listener to our ScrollingTable’s scrolls 🙂 , this is done by invoking the method addScrollListener on the table (t) after defining the table (line 89 of our new class):

t.addScrollListener(this);

this line means that this class (TransactionView) is listening on the ScrollingTable (t) scroll event, and it will invoke the method doTableScroll whenever the user scrolls down/up the ScrollingTable (t).

Here you go, you have now a table that will tell you whenever the user is scrolling, your task now is to do what you want when the table fires scrolling event and put your stuff between the curly brackets {} of the method that we defined in the first step:

@Override
public void doTableScroll() {
      // Put your own code here ...
}

Here is the link of the new Dashboard on GitHub.

Thanks for reading 🙂