How to ignore specific private static function with PHPUnit?

Viewed 45

I'm new to PHPUnit and wondering is it possible to write a test for which ignore specific method.
The code is like examine whether $data is Valid or not, and if it find irregular data, send message to slack with it.
My question is, is it possible to run a test without sending alert message, like ignore sendAlert function?
If possible, I want to know how to write it, If not, I want know why and how to make this code testable.
Thanks!!

example code )

    public static function isValid($data) {

      // some code here

      if (Valid) {
         return true;
      } else {
         // some code here to find irregular
           if (irregular) {
             self::sendAlert($data);
           }
         return false;
      }
    }

    private static function sendAlert($data) {
      // send alert to slack
      Example_Model_Slack::post($slackMsg, $channel);
    }

<?
class Example_Model_Slack
{
    public static function post($text, $channel = '') {
      // make $params from $text and $channel
      // POST
      $stream = [
            'http' => [
                'method'  => 'POST',
                'protocol_version' => 1.1,
                'content' => http_build_query($params),
            ],
        ];
        return file_get_contents(self::POST_URL, false, stream_context_create($stream));
    }
}
1 Answers

Edit after the question edit

If your code is in a namespace (which should be, it's good practice), it's extremely easy:

Create a new function in a separate file that is only included by your UnitTest file. This file should have the same namespace as your code. In this example, Example_Model_Slack is in the namespace Foobar\Models.

<?php
namespace Foobar\Models;

function file_get_contents(string $filename, bool $use_include_path = false, resource $context = ?)
{
  return 'Whatever you want';
}

When you call a function, the code looks for it:

  1. In the specifically used functions.
  2. In the same namespace.
  3. In the built-in functions.

Therefore, your code will use the built-in file_get_contents (namely \file_get_contents), but your test will use the one in the same namespace (namely \Foobar\Models\file_get_contents).

Original answer

The easiest would be to actually call sendAlert, but to mock the call to its content. As you didn't provide the code of that method, I can't be more precise, juste browse through the doc and figure it out by yourself or, alternatively, show us the code.

For a theorectical and general answer: your sendAlert method probably uses one that is provided by an external vendor, let's say \SlackApi\Slack::send($message). In that case, you could mock the provided \SlackApi\Slack class to replace the send method with one that doesn't actually send anything but still returns the expected data.

Related