You are here

class AddClassTest in Examples for Developers 3.x

Same name and namespace in other branches
  1. 8 phpunit_example/tests/src/Unit/AddClassTest.php \Drupal\Tests\phpunit_example\Unit\AddClassTest

AddClass units tests.

This test case demonstrates the following PHPUnit annotations:

  • dataProvider
  • expectedException.

PHPUnit looks for classes with names ending in 'Test'. Then it looks to see whether that class is a subclass of \PHPUnit_Framework_TestCase. Drupal supplies us with Drupal\Tests\UnitTestCase, which is a subclass of \PHPUnit_Framework_TestCase. So yay, PHPUnit will find this class.

In unit testing, there should be as few dependencies as possible. We want the smallest number of moving parts to be interacting in our test, or we won't be sure where the errors are, or whether our tests passed by accident.

So with that in mind, it's up to us to build out whatever dependencies we need. In the case of AddClass, our needs are meager; we only want an instance of AddClass so we can test its add() method.

@group phpunit_example @group examples

Hierarchy

Expanded class hierarchy of AddClassTest

Related topics

File

modules/phpunit_example/tests/src/Unit/AddClassTest.php, line 36

Namespace

Drupal\Tests\phpunit_example\Unit
View source
class AddClassTest extends UnitTestCase {

  /**
   * Very simple test of AddClass::add().
   *
   * This is a very simple unit test of a single method. It has
   * a single assertion, and that assertion is probably going to
   * pass. It ignores most of the problems that could arise in the
   * method under test, so therefore: It is not a very good test.
   */
  public function testAdd() {
    $sut = new AddClass();
    $this
      ->assertEquals($sut
      ->add(2, 3), 5);
  }

  /**
   * Test AddClass::add() with a data provider method.
   *
   * This method is very similar to testAdd(), but uses a data provider method
   * to test with a wider range of data.
   *
   * You can tell PHPUnit which method is the data provider using the
   * '@dataProvider' annotation.
   *
   * The data provider method just returns a big array of arrays of arguments.
   * That is, for each time you want this test method run, the data provider
   * should create an array of arguments for this method. In this case, it's
   * $expected, $a, and $b. So one set of arguments would look a bit like this
   * pseudocode:
   *
   * @code
   * array( valueForExpected, valueForA, valueForB )
   * @endcode
   *
   * It would then wrap this up in a higher-level array, so that PHPUnit can
   * loop through them, like this pseudocode:
   *
   * @code
   * return array( array(first, set), array (next, set) );
   * @endcode
   *
   * This test has a better methodology than testAdd(), because it can easily
   * be adapted by other developers, and because it tries more than one data
   * set. This test is much better than testAdd(), although it still only
   * tests 'good' data. When combined with testAddWithBadDataProvider(),
   * we get a better picture of the behavior of the method under test.
   *
   * @dataProvider addDataProvider
   *
   * @see self::addDataProvider()
   */
  public function testAddWithDataProvider($expected, $a, $b) {
    $sut = new AddClass();
    $this
      ->assertEquals($expected, $sut
      ->add($a, $b));
  }

  /**
   * Test AddClass::add() with data that should throw an exception.
   *
   * This method is similar to testAddWithDataProvider(), but the data
   * provider gives us data that should throw an exception.
   *
   * This test uses the setExpectedException() method to tell PHPUnit that
   * a thrown exception should pass the test. You specify a
   * fully-qualified exception class name. If you specify \Exception, PHPUnit
   * will pass any exception, whereas a more specific subclass of \Exception
   * will require that exception type to be thrown.
   *
   * Alternately, you can use try and catch blocks with assertions in order
   * to test exceptions. We won't demonstrate that here; it's a much better
   * idea to test your exceptions with setExpectedException().
   *
   * @dataProvider addBadDataProvider
   *
   * @see self::addBadDataProvider()
   */
  public function testAddWithBadDataProvider($a, $b) {
    $sut = new AddClass();
    $this
      ->expectException(\InvalidArgumentException::class);
    $sut
      ->add($a, $b);
  }

  /**
   * Data provider for testAddWithDataProvider().
   *
   * Data provider methods take no arguments and return an array of data
   * to use for tests. Each element of the array is another array, which
   * corresponds to the arguments in the test method's signature.
   *
   * Note also that PHPUnit tries to run tests using methods that begin
   * with 'test'. This means that data provider method names should not
   * begin with 'test'. Also, by convention, they should end with
   * 'DataProvider'.
   *
   * @return array
   *   Nested arrays of values to check:
   *   - $a
   *   - $b
   *   - $expected
   *
   * @see self::testAddWithDataProvider()
   */
  public function addDataProvider() {
    return [
      [
        5,
        2,
        3,
      ],
      [
        50,
        20,
        30,
      ],
    ];
  }

  /**
   * Data provider for testAddWithBadDataProvider().
   *
   * Since AddClass::add() can throw exceptions, it's time
   * to give it some data that will cause these exceptions.
   *
   * add() should throw exceptions if either of it's arguments are
   * not numeric, and we will generate some test data to prove that
   * this is what it actually does.
   *
   * @see self::testAddWithBadDataProvider()
   */
  public function addBadDataProvider() {
    $bad_data = [];

    // Set up an array with data that should cause add()
    // to throw an exception.
    $bad_data_types = [
      'string',
      FALSE,
      [
        'foo',
      ],
      new \stdClass(),
    ];

    // Create some data where both $a and $b are bad types.
    foreach ($bad_data_types as $bad_datum_a) {
      foreach ($bad_data_types as $bad_datum_b) {
        $bad_data[] = [
          $bad_datum_a,
          $bad_datum_b,
        ];
      }
    }

    // Create some data where $a is good and $b is bad.
    foreach ($bad_data_types as $bad_datum_b) {
      $bad_data[] = [
        1,
        $bad_datum_b,
      ];
    }

    // Create some data where $b is good and $a is bad.
    foreach ($bad_data_types as $bad_datum_a) {
      $bad_data[] = [
        $bad_datum_a,
        1,
      ];
    }
    return $bad_data;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AddClassTest::addBadDataProvider public function Data provider for testAddWithBadDataProvider().
AddClassTest::addDataProvider public function Data provider for testAddWithDataProvider().
AddClassTest::testAdd public function Very simple test of AddClass::add().
AddClassTest::testAddWithBadDataProvider public function Test AddClass::add() with data that should throw an exception.
AddClassTest::testAddWithDataProvider public function Test AddClass::add() with a data provider method.
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals Deprecated protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.
UnitTestCase::setUp protected function 308
UnitTestCase::setUpBeforeClass public static function