2

So I've decided to investigate using seams in PHPUnit, but I came across a problem

I rearranged my class in a way that I broke the dependencies to database class

db_Class::getMyData($vars);

became

self::getMyData($vars);

and I added functions to my code

protected static function getMyData($vars) {
    return db_Class::getMyData($vars);
}

This was done so I can make a class that inherits this class and overloads the getMyData function. To be able to alter it when I run my test cases.

So for example in the seam class that extends the class above and overloads that function:

protected static function getMyData($vars) {
    return array('id'=>1, 'name'=>"My Name");
}

This would be very useful, as I can alter the data as I like. However when using PHPUnit you have the possibility to run mocks using $this->getMock and similar. Would I ever be able to achieve this inside the seam class.

I'm trying to look for a solution where I am not using a dependency injector, which would be my other alternative, not so bad at all, just want to evaluate both alternatives.

Michael C. Feathers expressed a seam to be the following:

A seam is a place where you can alter behavior in your program without editing in that place.

So I might not get the full picture, and I've been trying to get it for a while now, and I just cant get my head around it. Please comment if you have any ideas or questions.

What I ask for is a way to work with mocks easy in different scenarios. I dont always want to return the same value in the seam, sometimes I want to return null to get an error, and sometimes an array with correct data, and sometimes something else probably.

Thanks

Oldek
  • 2,679
  • 5
  • 23
  • 25

3 Answers3

3

Because you must reference the class directly when calling static methods, you cannot override them as you can non-static methods. Static methods make testing difficult. I won't bother repeating what's written there, and I highly recommend following the links in the answers.

In any case, why is that method static? Being protected, you can call it only from the same class or its subclasses. Can you post more of the context here? How do you intend to use it, and where will you test it? Can you change it to non-static?

Community
  • 1
  • 1
David Harkness
  • 35,992
  • 10
  • 112
  • 134
0

The idea here is that you can prepare testable version of X where only thing overriden will be getMyData:

protected static function getMyData($vars) {
    return $some_dummy_data;
}

You write tests for X indirectly trough TestX. Now lets assume that you change something in original X that breaks it. TestX does inherit that broken code, thus its tests fail. Exactly what we wanted!

przemo_li
  • 3,932
  • 4
  • 35
  • 60
0

I found an answer to my question here:

http://sebastian-bergmann.de/archives/885-Stubbing-Hard-Coded-Dependencies.html

Oldek
  • 2,679
  • 5
  • 23
  • 25
  • Unfortunately this page is now dead. However there is an archived version of it which is invaluable when explaining the importance of seams to unit-test https://web.archive.org/web/20120102095742/https://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html – Nathaniel Rogers Oct 05 '22 at 03:30