-1

I have a model that overloads the where function.

My overloaded method looks like this:

public function where($column, $operator = null, $value = null, $boolean = 'and')
{
    if (in_array($column, $this->metaFields))
    {
        $value    = '%"' . $column . '":"' . $value . '"';
        $column   = 'meta';
        $operator = 'like';
    }

    return parent::where($column, $operator, $value, $boolean);
}

Now using phpunit and mockery I am trying to test this class, I need to test my overloaded where function, all I really care about is what the values are that get passed to parent::where()

My question is, is it possible/how would I mock the parent class so I can do

$metaField = 'colour';
$value     = 'blue';
//on the parent
->shouldReceive('where')->with(['meta', 'like', '%"colour":"blue"%'])->once();

//on the model I am testing
$model->where('colour', 'blue');
hakre
  • 193,403
  • 52
  • 435
  • 836
Hailwood
  • 89,623
  • 107
  • 270
  • 423

1 Answers1

1

all I really care about is what the values are that get passed to parent::where()

No, you don't. This is an implementation detail you do not need to care about at all with unit testing. Just relax.

Edit: That was no joke, however if your design requires this, you should favor composition over inheritance so that you can actually mock that "parent" and inject it, therefore test such an expectation. By definition, the parent of a mock in mockery is the class, so the parent in this case is the class with the overloaded method, not it's parent. You can not mock "parents" with mockery (and not with any other PHP mock library I'm aware of).

hakre
  • 193,403
  • 52
  • 435
  • 836
  • The reason we have this method is because we are storing meta information that doesn't really warrant it's own column as a json blob in a `meta` column. this function *should* allow us to successfully query the meta-columns as if they were real columns. So I thought that this would be something worth testing? can you tell me why I don't need to test it? (Not my downvote btw) – Hailwood Jun 22 '13 at 02:12
  • Only test the *public* interface, in this case the return value. Just test with some boundary values so that you catch the error cases if you don't trust writing that code. Also you should have written that failing *before* implementing the routine then you wouldn't be so much wondering afterwards. E.g. if the parent class has it's unit tests and all they pass, you only need to test the additional functionality here, that is that you can invoke that method and you get back the expected result. – hakre Jun 22 '13 at 02:20
  • About the why: How the where method retrieves the return value is not of interest for the rest of the application. Only that it works. So you don't need to test implementation details. E.g. you don't need to test that in_array() works for example, that is the job of PHP QC. – hakre Jun 22 '13 at 02:24
  • Shall we continue this in chat? http://chat.stackoverflow.com/rooms/32194/continued-discussion-of-question-17246594 – Hailwood Jun 22 '13 at 02:28
  • > This is an implementation detail you do not need to care about at all with unit testing This is very wrong. *Unit* testing implies testing of the internals of the application. Testing that "it works" is called *functional* testing. – XedinUnknown Oct 29 '17 at 08:13
  • Unit testing is not internal testing, it's unit-testing, the test of the public interface of the unit. Whether the unit under test has a parent class or not isn't (or better shouldn't be) of interest for a unit-test. – hakre Oct 31 '17 at 21:43