Mike Pearce – blog

Why do I even care what version your API is? Versioning your API with HATEOAS

Posted in APIs by Mike Pearce on August 26, 2010
Original image by zenera

I HATE OA(R)S. Original image by zenera

This is another in my unofficial series on stuff to do with REST. You can see the others by clicking here for API Anti-Patterns or here for Cookies and the RESTful API.

Notice what I did there? Think hard. I linked some other documents that you can GET. Click’em and you’ll:

GET: http://blog.mikepearce.net/2010/08/24/cookies-and-the-restful-api/

What I did there was provide you with two hypertext links, one to each of the other posts about REST that I’ve written. This is HATEOAS. You see,  you don’t actually need to know those two links above to be able to find them, you don’t even really need to know this link to THIS blog post, you only need to know my endpoint, which is http://blog.mikepearce.net. Navigate to there, and then you can get to each and every other page on my blog without having to know the URLs.

Even if you DID know my URLs (and by ‘know’ I mean bookmark, only the most diehard Mike Pearce fans memorise all my blog post URLs, dontcha Jon?) I might, one day, decide to change the schema, so they wouldn’t work. However, you’d get a 404 and a list of possible URLs, or I might even 301 redirect you if I was feeling nice (and this wasn’t hosted on wordpress.com). The thing about this hypermedia is that it’s so easy to get anywhere you like, the very definition of surfing.

CAN HAZ ENDPOINT. (Image by kwerfeldein)

So, now you’ve had a short tutorial on what HATEOAS means, Hypermedia As The Engine Of Application State, essentially means that your clients shouldn’t be building their own URIs. They should be requesting one of your endpoints and retrieving a list of URI with which they can interact with with one of the HTTP verbs (GET, PUT, DELETE, UPDATE, POST). The idea (which I illustrated above) is, that as an API provider, should you need to, you can change your URIs when you like and your clients will still know how to access all the resources of your API (if they’ve written their client to support that kind of thing). You could get away with one endpoint, the root of your API URI scheme. But it might be nice to provide one or two more which aren’t every going to change, perhaps:


http://api.yourcompany.com/users

http://api.yourcompany.com/links

Further, you can then provide your users with a list of properties that the API response will return at each of these endpoints, that links to the URIs they need to access to interact with your service. So, if the user were to:

GET: http://api.yourcompany.com/users

The response might be:

{
	"userMutateActions":
	{
		"add": "/users/add",
  		"update": "/users/updateUser",
  		"delete": "/users/deleteThatSucka"
  	},
  	"userReadOnlyActions"
  	{
  		"get.Details": "/users/$username",
  		"get.Email": "/users/$username/email",
  		"get.Dob": "/users/$username/dob
  	}
}

Now you’ve a contract with your clients that means they can visit any of the three endpoints and be able to navigate their way around the rest of your API. If you were a nice API provider you could provide examples of code for your clients to integrate into the software that interrogated your API for these endpoint URI indexes…

You see, I think that here it is a little fuzzy. The idea is that a client can and should be able to bookmark a URI it knows about and be able to call that URI and have your API still respond is one of the tenets of a REST API, but it’s at odds with HATEOAS.

Eggheads and Philosopers (Image by Dunechaser)

Eggheads and Philosopers (Image by Dunechaser)

Anyway, that’s for eggheads and philosophers. Use your best judgment to decide when and where to do this kind of thing, how many endpoints you have and what you provide as URIs to your clients.

I should really get to the point described in the title. But you’ve probably worked it out by now…

There are a couple of ways of versioning an API, check out slides 88 – 93 of my presentation in the API AntiPatterns presentation here, either on the URL, or in the body of a request or with primary and secondary URIs. The thing is, after I wrote that and while I spent a bit of time reading more about cookies, I decided that none of those methods of versioning were any good, the answer is…

… don’t actually bother with versioning. If you’re adhering to the HATEOAS contraint and you’ve created some good, solid endpoints, some documentation that creates contracts as to nomenclature of your URI properties with your clients, then you don’t need to version. Just change the URIs and the values of the URI properties at each endpoint and the client won’t even know you’ve done it.

Shhh, it’ll be our little secret!

Tagged with: , , , , ,

Cookies and the RESTful API

Posted in APIs by Mike Pearce on August 24, 2010

Right, after my presentation at PHPLondon this month, the most contentious issue was that of using cookies with your REST API. I said, in no uncertain terms, that you shouldn’t do it. There were a few cries from the audience which were akin to the flapping you hear in a parliamentary broadcast, Derick Rethans didn’t agree but had the grace not to publicly embarrass me* and one comment on the original post requesting a clarification of my statement.

So, to clarify!

One of the most important constraints of REST is that it should be stateless, that is, every request made to API should contain everything the application needs in order to service the request. Now, at it’s most terse, that is my clarification, however, the quicker witted and cleverer among you will be proud to announce that a cookie is part of a HTTP request, and you’d be right, so, more clarification is needed.

In order to get to my decision that cookies shouldn’t be used with a REST API, you have to consider HATEOAS (Hypertext As The Engine Of Application State). What this means is that, a client only needs to know one, well published, end point to your entire API and from there, they can navigate the whole damn thing. Many people have blogged on this (including the big man himself), so I shan’t go into it right now, take a look at those links, but it’s safe to say that your clients shouldn’t be building their own URIs, they should be given the URIs from the API. Following this through to it’s logical conclusion means that the client shouldn’t be storing anything that isn’t the well published end point, because you, as the service provider, could change the requirement of whatever it is the client has stored as a cookie on a whim and then the client is banjaxed.

An example you say? OK. Let’s assume for a moment that we all agree that storing login information on the client is NOT GOOD. Right? (Consider XSS briefly and you’ll understand why – although less relevant nowadays, it’s still relevant (just)). OK, so the only other logical thing we might want to store in a cookie is an authentication token. That seems fairly harmless in it’s implementation, no? Yes it is and really, we could end the post here as, at a push, this is probably the one thing that IS OK to store in a cookie.

But I don’t sanction it.

Why? Because it doesn’t adhere to the constraints of HATEOAS and statelessness. Now the client has a cookie with an authentication token in it, you cannot change the way you authenticate, or the way the token is created without breaking the link between your API and each client that is using that token. If you publish a change to your REST API which handles the tokens differently, each and every cookie token will be useless.

Granted, this example doesn’t really offer anything that couldn’t be fixed with another login, but that’s not the point. The point is, it’s not RESTful.

To wit; this is a rule you can break and, probably, get away with it. However, you’ll feel dirty as it won’t be REST; try not to do it, make Roy happy.

*Although, he did heckle me on many other points. ;)

10 Hadoop-able Problems (a summary)

Posted in Hadoop by Mike Pearce on August 18, 2010

So, the new company I work for, Affiliate Window, are pretty awesome. Technically, they’re not driven by what is cool, or what the latest buzzword is on The Twitter that one of the directors saw on the telebox. They do what is necessary to get the job done, using the best tools. If this requires some in house dev, then time is found. If there’s a cool bit of tech from outside which fits the problem, then they’ll try it.

They’re also not hemmed in by the corporate, big enterprise world of “it’s the way others do it, so we should to”. They’re also good at long-term investment in their team and their tools. Plus, I get to use Ubuntu as my desktop. Rock on.

Anyway, a meeting was arranged for today where we could watch a presentation on Cloudera’s Hadoop (which you can see here at GoMeeting, although only on windows and only after registering (great, more vendor lockin!)). It was called ’10 Common Hadoopable Problems’ given by Jeff Hammerbacher (their Chief Scientist no less!) and was basically things that you can do with hadoop (that isn’t counting words…). I thought I would summarise them here, although I’d encourage every last one of you to watch it as it’s pretty interesting.

  1. Modelling True Risk – If you think about this in the context of banks or other financial institues (which is, well, banks) this is a really useful way of burrowing deeper into your customers. You can suck in data about their spending habits, their credit, repayments everything. Munge it all together and squeeze out an answer on whether to lend them more money.
  2. Customer Churn Analysis – Hadoop was used here to analyse how a telco retained customers. Again, data from many different sources, including social networks AND the calls themselves (recorded and then voice analysed, I guess) were used to work out how and why the company were losing or gaining customers.
  3. Recommendation engines – I don’t really need to explain this one do I? Thinking about this in terms of Google, this is like the ranking algorithm. Sucking in a bunch of factors like; popularity, link depth, buzz on Twitter etc and then scoring links for display in score order later.
  4. Ad Targeting – Similar to the recommendation engine, but with the added dimension of the advertiser paying a premium for better ad-space
  5. Point Of Sale Transaction Analysis – On this face of it, this seems simple and straightforward; analysing the data that is provided by your P.O.S device (your till). However, this could also include other factors like weather and local news, which could influence how and why consumers spend money in your store.
  6. Analysing Network Data To Predict Failure – The example given here was that of an electricity company which used smart-somethings to measure the electricity flying around their network. They could pump in past failures and current fluctuations and then pass the whole lot into a modelling engine to predict where failures would occur. It turned out that seemingly unconnected, small anomolies on the system were connected after all. This data wouldn’t have been able to be mined any other way.
  7. Threat Analysis/Fraud Detection – Another one for the financial sector and very similar to Modelling True Risk. Hadoop can be used to analyse spending habits, earnings and all sorts of other key metrics to work out a transaction is fraudulent. Yahoo! use Hadoop with this pattern to ascertain whether a certain piece of mail heading into Yahoo! Mail is actually spam.
  8. Trade Surveillance – Similar to Threat Analysis and Fraud Detection, but this time pointed squarely at the markets, analysing gathered historical and current live data to see if there is Inside Trading or Money Laundering afoot!
  9. Search Quality – Similar to the recommendation engine. This will analyse search attempts and then try to offer alternatives, based on data gathered and pumped into Hadoop about the links and the things people search for.
  10. Data “Sandbox” – This is probably the most ambigious, but the most useful Hadoop-able problem. A data sandbox is just somewhere to dump data that you previously thought was too big, or useless or disparate to get any meaningful data from. Instead of just chucking it away, throw it into Hadoop (which can easily handle it) then see if there IS data you can glean from it. It’s cheap to run Hadoop and anyone can attach a datasource and push data in. It allows you to make otherwise arbitrary queries about stuff to see if it’s any use!

As you can see, most of these boil down to “Aggregate Data, Score Data, Present Score As Rank”, which, at it’s simplest, is what Hadoop can do. But the introduction of the idea of a Data Sandbox and the ability, using Sqoop, to push the analysed data back into a relational database (for a data warehouse for example) means that you can run Hadoop independently and prove it’s worth in your business very cheaply.

API Anti-Patterns (how NOT to write a RESTful API)

Posted in APIs, php by Mike Pearce on August 8, 2010

I had the honor of giving another talk at PHPLondon this month. Although I only had two weeks notice to research and write the thing, I think I managed to pull it off!

The talk was on API Anti-Patterns. I’d originally thought about doing a talk on How To Write a RESTful API, but the topic is enormous and sprawling and I only had 30 mins. So, I flipped the idea on it’s head and wrote about the things which we find with supposedly RESTful APIs which really aren’t RESTful. It’s shorter and, more importantly, funnier. So, below you’ll find the video and the slides from the night. Get in touch if you have any questions.

(more…)

It’s always greener…

Posted in Irrelevant by Mike Pearce on July 26, 2010

It’s with great emotion that I am to leave Jellyfish, where I currently work, and head over to join the team at Affiliate Window. My time at Jellyfish has been interesting. I leave more tooled up than when I arrived but also weathered and with a firm understanding of how small businesses become big businesses and the mistakes they make on the journey…

Well, I certainly don’t want to burn bridges and, to be honest, I don’t have any dirty laundry to air. The people I have worked with at Jellyfish have been an inspiration to me – I’ve learnt a hell of a lot from my colleagues and they’ve since become friends; good friends whom I shall endeavour to keep in touch with. I’ve picked up a lot of new skills along the way and even worked on one or two interesting projects (the last project being the  most interesting, but also commercial sensitive, so it’ll have to wait for launch until I say anything!).

So. Thanks Jellyfish – may your tendrils be wobbly and your body see-through and your life-span infinite. It’s been a blast. Perhaps we’ll waltz again some day (if you need a dev-manager, or a product owner ;) ).

Writing Effective User Stories

Posted in Uncategorized by Mike Pearce on July 2, 2010

This months PHPLondon took on a different format. Usually there is one speaker who gives a talk, but this month, the new President and the committee decided they’d take a different approach, in the form of lightening talks. Whoever wanted to could stand up and talk for five minutes on any subject relevant to PHP or development.

I offered to do a talk on Writing Effective User Stories (which I’d give before at my place of work) and I thoroughly enjoyed it, I just hope that the audience did too! As well as the video above, you can view the slides by clicking here and the handout (which I didn’t hand out!) here. Or you can see them both after the jump. Contact me if you have any questions or would like to know more.

(more…)

git status on multiple repos

Posted in Code, git, python by Mike Pearce on June 16, 2010
Show_status

git status is now better

Often a lot of the work I do is on services. This means that, in any given day, I’ll perhaps be working on one or more repos. As is the way of git, I commit often to the local working branch and they push to the master at the end of the day, or whenever I’ve got feature, or patch of fix or whatever that needs to go back upstream. First thing in the morning, I’ll also do a pull for each repo I’m going to work on, including dependent repos.

If you’ve got a lot or repos, this quickly gets tedious to cd into each directory, run git status, then git push or git pull, cd back out, then into the next directory, etc etc.

So, I wrote a wee python script called ‘show_status’

Usage: show_status [options]

Show Status is awesome. If you tell it a directory to look in, it'll scan
through all the sub dirs looking for a .git directory. When it finds one it'll
look to see if there are any changes and let you know. It can also push and
pull to/from a remote location (like github.com) (but only if there are no
changes.) Contact mike@mikepearce.net for any support.

Options:
  -h, --help            show this help message and exit
  -d DIRNAME, --dir=DIRNAME
                        The directory to parse sub dirs from
  -v, --verbose         Show the full detail of git status
  -r REMOTE, --remote=REMOTE
                        Push to the master (remotename:branchname)
  -p PULL, --pull=PULL  Pull from the master (remotename:branchname)

Just running ‘show_status’ will always run a non-verbose check on any sub dirs in your current dir, so:

%> show_status
-- Starting git status...
Scanning sub directories of /home/sites/
--/home/sites/gitstatus        : No Changes
--/home/sites/projectone    : No Changes
--/home/sites/project2        : No Changes
Done

You can also pass in a directory that you want to use, this is useful if you wanted to use it in other scripts, or if you’re not in a root directory:

%> show_status -d/home/sites

You can add a pull request, which will pull from a remote master. It’s important to note that it’ll only pull from a remote master if there are no local changes waiting to be committed. This is to force you to manage your merges carefully.

%> show_status -pmikepearce:master

Finally, you can do push requests as well, again, this will only work on repos where there is nothing waiting to be commited:

%> show_status -rmikepearce:master

You can grab the whole thing on github (Git Status), or just clone/fork here: git@github.com:MikePearce/Git-Status.git

Tagged with: , , ,

A little bit of git

Posted in git by Mike Pearce on June 1, 2010

Using git after SVN is like driving a Ferrari after driving a Jaguar. Nimble, speedy, lovely. My word it’s beautiful.

Anyway, I’m learning my way around it and, recently, came across these two lovely things:

Colouring the git output (from @catchamonkey)

I didn’t realise how useful colouring the output of things like git diff and git status etc was until I’d done it. Follow the below:

%> vi ~/.gitconfig

This will open the global .gitconfig file for your CURRENT user in vi. It will probably look something like this:

[user]
 name = Mike Pearce
 email = mike.pearce@jellyfish.co.uk

Below all that, you’ll need to add this:

[color]
        ui = auto
[color "branch"]
        current = yellow reverse
        local = yellow
        remote = green
[color "diff"]
        meta = yellow bold
        frag = magenta bold
        old = red bold
        new = green bold
[color "status"]
        added = yellow
        changed = green
        untracked = cyan

Obviously, you can change the colours to suit your particular pallete, but the above are pretty cool!

Global Ignorance (via @nefarioustim)

Sometimes, you’ll want to ignore the same file for each git repo. You can add the ignored files to the git repo itself, or, if you know there’ll always be a file or files you want to ignore, you can add it to git excludes.

I use netbeans on a mac, so I generally ignore the following:

  • .DS_Store
  • ./nbproject
  • *.pc (compiled python code)

You can do it by editing the .gitconfig file again:

%> vi ~/.gitconfig

Then adding the following lines somewhere:

[core]
 excludesfile = ~/.gitexcludes

OK, save then, then do this:

%> vi ~/.gitexcludes

and add each one on a new line:

DS_Store
nbproject
*.pc

Save that et voila. You’ll never be troubled with those files being added to your repo again.

Tagged with: , , , ,

Namespaces, unit testing and dependency injection (with typehinting)

Posted in Uncategorized by Mike Pearce on May 26, 2010
Bad Medicine by Vermin Inc @ Twitter

Injection Dependency STRAIGHT INTO YOUR OCCIPITAL LOBE!

I’ve struggled with the concept of unit testing and how to deal with dependencies a lot in the past. The solution seemed to be just out of reach. I knew there WAS a solution and not a hacky one either, one that was elegant and worked well. I never really found it. PHPUnit seemed to be well written but not particularly well documented and a lad like myself, one who is a few sandwiches short of a picnic at times, almost gave up.

Almost.

I know and understand the benefits of unit testing and I understand the disadvantages. Unit testing is a weapon that can mite out retribution and vengence if not used properly. There are plenty of posts on the web about the wrong way to unit test and the hazards of them, so I’ll leave you to find them.

Aaaaaanyway, writing your application so that it uses the dependency injection pattern is the best method for making sure it’s uncoupled and modular enough to write some efficient, unit tests (ie: tests that test just a unit of code). Especially when they depend on objects which link to databases, or web services or other crazy stuff that you don’t really want or need to instantiate in your test suite. The problem that I encountered time and time again was when you mocked an object to pass into one test, then you wanted to actually test the REAL version of the object you’d previously mocked or stubbed, you couldn’t. PHP would throw an error:

Code.php:

<?php
    class badger {
    }
    class badger {
    }

%> php code.php
Fatal error: Cannot redeclare class badger

See? It’s a predicament, especially when you want to do some unit testing.

<?php
class weather {
    /**
     * @param string $postcode
     * @return object
     */
    public function getWeatherFromPostcode($postcode) {
        //.. connect to a web service
        $weather = new ThirdPartyWeatherService();
        return $weather->getWeatherAt($postcode);
    }

}

class stuff {

    public function isItRaining($postcode)
    {
        return (
                    $this->weather->getWeatherFromPostcode($postcode)
                          ->precipitation = 'RAIN'
                        ? TRUE
                        : FALSE
               );
    }

    public function injectWeatherObject(weather $o) {
        $this->weather = $o;
    }
}

class doTest extends PHPUnit_Test_Case {

    public function testIsItRaining() {
        $stuff = new stuff();
        $stuff->injectWeatherObject(new weather());
        $this->assertTrue($stuff->isItRaining('RH2 9SS'));
    }
}

The problem with the above code is that, the test may pass or false randomly depending on the weather. Clearly, this is a nightmare! No one thinks that there code is going to behave differently depending on the weather, that’s CRAZY TALK MAN! Well, this code would, especially if the weather is as strange as it is in Reigate.

So, how to get round this: dependency injection and mock objects. See, we had the foresight to inject the weather object into the stuff object. That means we’re halfway there (if you’d just instantiated the weather object in the stuff object, this would be much harder). To workout the solution to this, we need to ask a question: What are we testing?

The answer is, we’re testing the stuff class and, more specifically, the isItRaining() method. So, what do we need to do to test that? Well, for a start, we don’t actually need the full weather object (which might connect to a 3rd party service, which in turn, might be down, or slow or whatever – meaning the test might fail NOT because the unit is broken, but because a dependency is…), we only need to AN object with a ‘precipitation’ property. So, this means we can mock it up. Woo!

Code.php:

class weather {
    /**
     * @param string $postcode
     * @return object
     */
    public function getWeatherFromPostcode($postcode) {
        $w = new stdClass;
        $w->precipitation = 'RAIN'
        return $w;
    }

}

class stuff {

    public function isItRaining($postcode)
    {
        return (
                    $this->weather->getWeatherFromPostcode($postcode)
                          ->precipitation = 'RAIN'
                        ? TRUE
                        : FALSE
               );
    }

    public function injectWeatherObject(weather $o) {
        $this->weather = $o;
    }
}

class doTest extends PHPUnit_Test_Case {

    public function testIsItRaining() {
        $stuff = new stuff();
        $stuff->injectWeatherObject(new weather());
        $this->assertTrue($stuff->isItRaining('RH2 9SS'));
    }
}

Now, we know that it’ll ALWAYS be raining in Reigate (which sucks, but well, what can you do? All in the name of great testing, right?). This test will now pass, unless someone changes isItRaining() and it breaks. But that’s what unit testing is for.

Huzzah, let’s party. Except, we’ve introduced a problem here; what happens if we now weant to test a method in the REAL weather object:

Code.php


class weather {

    public function getTypesOfCloud($type)
    {

        $clouds = array
        (
            'high' =>
                array('Cirrus', 'Cirrocumulus', 'Cirrostratus')
            'medium' =>
                array('Altostratus', 'Altocumulus',)
            'low' =>
                array('Stratocumulus', 'Stratus',)
        );
        if (isset($clouds[$type])) {
            return $clouds[$type];
        }
        else {
            return FALSE;
        }

    }
    /**
     * @param string $postcode
     * @return object
     */
    public function getWeatherFromPostcode($postcode) {
        ..
    }
}
class weather {
    /**
     * @param string $postcode
     * @return object
     */
    public function getWeatherFromPostcode($postcode) {
        $w = new stdClass;
        $w->precipitation = 'RAIN'
        return $w;
    }

}

class stuff {

    public function isItRaining($postcode){ ... }

    public function injectWeatherObject(weather $o) { ... }
}

class doTest extends PHPUnit_Test_Case {

    public function testIsItRaining() { ... }

    public function testGetClouds()
    {
        $weather = new weather();
        $this->assertEquals(
            array('Cirrus', 'Cirrocumulus', 'Cirrostratus'),
            $weather->getTypesOfClouds('high')
        )
}

%> php code.php
Fatal error: Cannot redeclare class weather

OMFG! Now we’ve got two classes called the same thing, this makes it impossible to TEST THEM OMG NOO!

I should mention here that you’ll probably not have all your tests in one file, they’ll probably be split across multiple files and directories. They’re all in one file here to make things easier. However, this doesn’t mean you won’t get the same problem.

The easier thing to do would be to rename the mock weather object to something like ‘weatherMock’, but we can’t because our stuff class expects the object that is injected to be an instance of the ‘weather’ class.

“Well, remove the typehinting dumbass!” I hear you cry, throwing your hands in the air.

I could, but I shan’t. Because I WANT the typehinting there, it’s a conract and I am BOUND by it. I must have a weather object passed in, I can’t have ANY OLD object being passed in now can I? What would happen if someone passed in a ‘cheese’ object? DOES CHEESE HAVE PRECIPITATION?

Anyway, this is how I chose to solve this problem:

Code.php

<?
namespace Weather {
    require_once 'PHPUnit/Framework.php';
    abstract class abstractWeather {
        public function getTypesOfCloud() {}
        public function getWeatherFromPostcode() {}
    }

    class weather extends abstractWeather {

        public function getTypesOfCloud($type)
        {

            $clouds = array
            (
                'high' =>
                    array('Cirrus', 'Cirrocumulus', 'Cirrostratus'),
                'medium' =>
                    array('Altostratus', 'Altocumulus'),
                'low' =>
                    array('Stratocumulus', 'Stratus'),
            );
            if (isset($clouds[$type])) {
                return $clouds[$type];
            }
            else {
                return FALSE;
            }

        }
        /**
         * @param string $postcode
         * @return object
         */
        public function getWeatherFromPostcode($postcode) {
            // Commented as this doesn't actually exist.
            //$weather = new ThirdPartyWeatherService();
            //return $weather->getWeatherAt($postcode);
        }
    }
}
namespace WeatherMock {

    class weather extends \Weather\abstractWeather {

        /**
         * @param string $postcode
         * @return object
         */
        public function getWeatherFromPostcode($postcode) {
            $w = new \stdClass;
            $w->precipitation = 'RAIN';
            return $w;
        }

    }

}

namespace Main {
    class stuff {

        public function IsItRaining($postcode) {
            return (
                        $this->weather->getWeatherFromPostcode($postcode)
                                      ->precipitation = 'RAIN'
                            ? TRUE
                            : FALSE
            );
        }

        public function injectWeatherObject(\Weather\abstractWeather $o) {
            $this->weather = $o;
        }
    }

    class doTest extends \PHPUnit_Framework_TestCase {

        public function testIsItRaining() {
            $stuff = new stuff();
            $stuff->injectWeatherObject(new \WeatherMock\weather());
            $this->assertTrue($stuff->isItRaining('RH2 9SS'));
        }

        public function testGetClouds()
        {
            $weather = new \Weather\weather();
            $this->assertEquals(
                array('Cirrus', 'Cirrocumulus', 'Cirrostratus'),
                $weather->getTypesOfCloud('high')
            );
        }
    }
}

So, the solution is two fold.

  1. I made both the weather classes (real and mock) an extension of the abstractWeather class. This is good, because it means my contract is still in place (if a little more flexible) and I can force people to use the methods prescribed.
  2. I wrapped the abstract class and the real object in a namespace and the mock weather object in another namespace. This means I can have two instances of a class named ‘weather’ as they reside in different namespaces. I could have named the mock weather object as ‘weatherMock’ and not had the namespaces, but adding them makes it much cleaner. If I know I’m using namespaces and not going to get into trouble with conflicting error names, I can be confident that, with a HUGE library of tests, when they’re all run together, I’m not going to get the error (I don’t know if a colleague created a weatherMock() class two days ago for a different part of the application, but for use in the same suite of tests – using namespaces means it doesn’t matter).

Now, you could use interfaces instead of abstract classes, but I prefer the abtract classes as they give you something concrete to work from and, really, if you’re wanting to ride modular, encapsulated code, then you SHOULD be using abstract classes.

The only other thing to remember (which caught me out) is that stdClass lives in the global space, so, whenever instantiating a new stdClass, it must be pre-pended with a forward slase: \stdClass (the same goes for anything that ISN’T in a namespace when you’re working in one: \PHPUnit_Framework_TestCase

Feel free to copy this code and run it in your own environment, it *should* run!

This is not the only, or definitive method of achieving this. But I think it fits my ideal of having an elegant solution and it means the actual code (and not the tests) isn’t mauled about JUST to make the tests fit. Which is where a lot of unit testing falls down.

If you have another method or other ideas for how to get round dependcy and classname conflicts, then I’d love to hear them. Please post in the comments below!

Google: please stop before you do evil…

Posted in Google, Irrelevant by Mike Pearce on May 25, 2010
evil pumpkin by Riv @ flickr

This could be Google (image by Riv @ flickr)

Will Googles new secure search page be evil? You betcha!

If Google make their search and serps pages load on a https (or SSL) URL, then any analytics software (with the exception of their own, natch ;) ) will be next to useless. Why? Because visitors landing on your non-https site from a https site will NOT have a referrer URL. Which means, you’ll have no idea where they came from, what their raw search term was or ANY of the cool stuff associated with a referrer URL.

PPC will still work and things on the querystring URL will be OK, so you’ll know exactly where the users came from. Google will also know everything about your visitors and so their analytics platform will still work as they’ll be able to track you and your underlying click.

This is a big problem and is causing a little bit of worry amongst those companies that compete against Googles analytics platform.

How can this be mitigated? Well, you could make all sites on the web secure. If you go from one SSL site to another, your referrer will be intact (assuming the certs are OK). Google could also append querystring parameters to any outbound click from an organic serp (?referer=google.co.uk&rawSearch=used+badgers).

Who knows? I’m interested to know what Google will do as this, to me, feels like they’re about to do something inherently evil (unless they’re planning on buying ALL companies that do analytics, or use the referrer for anything meaningful!)

Tagged with: , , , , , ,