PHPUnit require_once地獄からの脱出 2 autoloadを使うんや編

前回、PHPUnit require_once地獄からの脱出 1 まずはrequire_onceでテスト元のファイルをどう読み込むか編 で大分長々と書きましたが、PHPUnitでテストファイルからrequire_onceでテスト元のファイルを読みだすのが面倒だという話です。

どうすればいいのかといいますと、phpunit.xmlを下記のように書き換えます。

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
        bootstrap = "vendor/autoload.php"
        colors = "true">
</phpunit>

下記が肝心の部分です。

bootstrap = "vendor/autoload.php"

ついでに、色がつくようにしています。

colors = "true"

緑の光あれ。

MonkeyTest.phpから、

require_once “class/Monkey.php”;

を消してみます。

<?php

use MonkeyWorld\Monkey; //追加
use PHPUnit\Framework\TestCase;

class MonkeyTest extends TestCase
{

    public function testScream()
    {
        $monkey = new Monkey();
        ob_start();
        $monkey->scream();
        $actual = ob_get_clean();
        $expected = 'ウキー!!!';
        $this->assertEquals($expected, $actual);
    }

}

testScreamを実行してみます。

OKです!緑の色もついて、みやすいですね!( ˊᵕˋ )

テスト元のMonkey.php に talkToChimpanzee()というメソッドが追加されました。

<?php
namespace MonkeyWorld;

class Monkey
{

    public function scream(){
        echo "ウキー!!!";
    }

    public function talkToChimpanzee(){
        Chimpanzee::talk();
    }

MonkeyTest.phpもtalkToChimpanzeeをテストできるように書き換えます。

use PHPUnit\Framework\TestCase;

class MonkeyTest extends TestCase
{

    public function testScream()
    {
        $monkey = new Monkey();
        ob_start();
        $monkey->scream();
        $actual = ob_get_clean();
        $expected = 'ウキー!!!';
        $this->assertEquals($expected, $actual);
    }

   public function testTalkToChimpanzee()
    {

        $monkey = new Monkey();
        ob_start();
        $monkey->talkToChimpanzee();
        $actual = ob_get_clean();
        $expected = 'こんにちは。おいらチンパンジーだよ。';
        $this->assertEquals($expected, $actual);

    }
}

今度はMonkeyTest.phpのMonkeyTest.classをテストとして実行してみます。

OKですね!

ちなみに、上記はPHPStormから実行していますが、コマンドプロンプトから実行すると、次のようになります。

phpunitの後に引数をつけずに、


phpunit tests/MonkeyTest.php

とするだけです 。

PHPUnitの設定ファイル、phpunit.xmlで実行の初期に

ところで、実験的にclass/Hoge.phpというやつを追加します。

<?php

class Hoge
{

    public function talk(){
        print "おいらHogeクラスです";
    }
}

こいつには、namespaceの宣言がないことに注意してください。

Monkey.phpにtalkToHogeというメソッドを追加します。

<?php
namespace MonkeyWorld;

class Monkey
{

    public function scream(){
        echo "ウキー!!!";
    }

    public function talkToChimpanzee(){
        Chimpanzee::talk();
    }

    public function talkToHoge(){
        Hoge::talk();
    }
}

MonkeyTest.phpに次のテストメソッドを足します。


    public function testTalkToHoge()
    {

        $monkey = new Monkey();
        ob_start();
        $monkey->talkToHoge();
        $actual = ob_get_clean();
        $expected = 'おいらHogeクラスです';
        $this->assertEquals($expected, $actual);

    }

MonkeyTestクラスを実行します。

Error : Class 'MonkeyWorld\Hoge' not found
D:\xampp\htdocs\autoloadSample\class\Monkey.php:16
D:\xampp\htdocs\autoloadSample\tests\MonkeyTest.php:38

というエラーが出て、実行が失敗したみたいです。(>_<)

というか、そもそも普通にこれはブラウザからPHPを実行しても実行できません。最初のサンプルでも使った、トップディレクトリにあるhoge.phpを実行します。

ディレクトリ・ファイル構成

hoge.phpは次の通りです。

<?php

require_once "vendor/autoload.php";

use MonkeyWorld\Monkey;
require_once "class/Hoge.php";

$monkey = new Monkey();
$monkey->scream();
echo "<br>";

$monkey->talkToChimpanzee();
$monkey->talkToHoge();

これを実行すると次のようになります。

 Fatal error: Cannot declare class Hoge, because the name  is already in use in D:\xampp\htdocs\autoloadSample\class\Hoge.php on  line 3

というエラーが出て実行できません。

あんまり深堀りできてないですが、これ、Hogeクラスが重複してますよってエラーなんですよね。なんででしょうか。わかる人、教えてください。m(_ _)m

仕方ないので、Hoge.phpに次のようにnamespaceをつけます。

<?php
namespace MonkeyWorld;

class Hoge
{

    public function talk(){
        print "おいらHogeクラスです";
    }
}

すると、エラーもなく実行できるようになります。

hoge.phpの実行結果↓

PHPUnitの実行結果↓

namespaceは大変大事ですね。

ちなみに、autoloadで読み込むnamespaceの指定については、下記の記事をご参考にしてみてください。

PHP require_onceを使わない、 autoloadを使ってクラスを読み込む方法 

2 Replies to “PHPUnit require_once地獄からの脱出 2 autoloadを使うんや編”

  1. ありがとうございます。PHPを始めたばかりで、autoloadの仕組みが良くわかっていませんでしたが、おかげで理解することができました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です