samedi 26 décembre 2015

Testing call of multiple methods in phpspec

In the past i always stumbled across a certain problem with phpspec:

Lets assume i have a method which calls multiple methods on another object

class Caller {
    public function call(){
       $this->receiver->method1();
       ...
       $this->receiver->method2();
    }
}

In BDD i would first write a test which makes sure method1 will be called.

function it_calls_method1_of_receiver(Receiver $receiver){
    $receiver->method1()->shouldBeCalled();
    $this->call();
}

And then i would write the next test to assure method2 will be called.

function it_calls_method2_of_receiver(Receiver $receiver){
    $receiver->method2()->shouldBeCalled();
    $this->call();
}

But this test fails in phpspec because method1 gets called before method2. To satisfy phpspec i have to check for both method calls.

 function it_calls_method2_of_receiver(Receiver $receiver){
    $receiver->method1()->shouldBeCalled();
    $receiver->method2()->shouldBeCalled();
    $this->call();
}

My problem with that is, that it bloats up every test. In this example it's just one extra line but imagine a method which builds an object with a lot of setters. I would need to write all setters for every test. It would get quite hard to see the purpose of the test since every test is big and looks the same.

I'm quite sure this is not a problem with phpspec or bdd but rather a problem with my architecture. What would be a better (more testable) way to write this?

For example:

public function handleRequest($request, $endpoint){
    $endpoint->setRequest($request);
    $endpoint->validate();
    $endpoint->handle();
}

Here i validate if an request provides all necessary info for a specific endpoint (or throw an exception) and then handle the request. I choose this pattern to separate validating from the endpoint logic.

Aucun commentaire:

Enregistrer un commentaire