M
M
midia212021-09-14 20:20:41
PHP
midia21, 2021-09-14 20:20:41

How to mock one class function in phpunit and leave the implementation of all the others (including the one being tested)?

I'm just getting started with testing. The task was to test the model function that calls the database update functions. I read that testing the database directly is quite difficult and decided to just mock the method that updates the values ​​in the database. Here is an example code of what I mean:

class Model {
  // метод который нужно мокнуть
  public function update($values) 
  {
    global $db;
    $db->query('update ...');
  }

  // функция которую нужно протестить
  public function change_time($start_time)
  {
    $end_time = $start_time + 1;

    $this->update([
      'start_time', $start_time,
      'end_time', $end_time
    ]);
  }
}


Naturally, in a real application, the data is more complex, and I need to check their correctness. Essentially, I just need to catch the incoming data in the update function. Something like that:

public function testEndTimeShouldBeCorrect()
{
  $mock = $this->getMockBuilder(Model::class)
    ->setMethods(['update'])
    ->getMock();

  $mock->expects($this->once())
    ->method('update')
    ->with($this->equalTo(5));


  Model::change_time(4);
}


I suspect that what I am asking about can hardly be achieved, but I will be grateful if you tell me any opportunity to test this case. Thank you.

PS Probably, it is possible to return the data that needs to be checked in the change_time function. But I think it will look illogical from the point of view of the program logic, and this is not worth sacrificing for the sake of tests.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vitsliputsli, 2021-09-14
@Vitsliputsli

Do not use global variables, but inject a dependency, then you can change the object and test what you need.

Probably it is possible to return data to be checked in the change_time function. But I think it will look illogical from the point of view of the program logic, and this is not worth sacrificing for the sake of tests.

On the contrary, it is not right to mix everything. Process the object, change the time in it or whatever you need, and saving this object to the database is a completely different operation.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question