4

興味深い問題があり、インターネットを検索しましたが、まだ答えが見つかりません。

私は、従業員が OOP を使用することを許可していない会社で働いています。それはちょっとばかげていますが、実務経験は貴重です。

次の関数を検討してください。

function get_setting_values_from_file( $parameter )
{
    exec("/usr/var/binary --options $parameter", $output, $return);
    $settings = file( $output[0] );
    foreach( $settings as $setting ) {
        if( strstr( $setting, "color") ) {
            $setting = explode( ":", $setting );
            return $setting[1];
        }
    }
    return false;
}

同様の機能を単体テストする必要があります。現在、テストに phpUnit を使用し、vfsStream ライブラリを使用してファイル システムをモックしexec("/usr/var/binary --options $parameter", $output, $return)ていますが、実際のシステムにアクセスせずに開発している場合、どのように呼び出しをモックしますか? このようなテスト ケースを処理するための推奨されるアプローチは何ですか?

すべてのフィードバックをお待ちしております。

4

2 に答える 2

6

exec()関数モック ライブラリを使用してモックできます。php-mock名前空間を使用する必要があるもの ( ) を作成しました

namespace foo;

use phpmock\phpunit\PHPMock;

class ExecTest extends \PHPUnit_Framework_TestCase
{

    use PHPMock;

    public function testExec()
    {
        $mock = $this->getFunctionMock(__NAMESPACE__, "exec");
        $mock->expects($this->once())->willReturnCallback(
            function ($command, &$output, &$return_var) {
                $this->assertEquals("foo", $command);
                $output = "failure";
                $return_var = 1;
            }
        );

        exec("foo", $output, $return_var);
        $this->assertEquals("failure", $output);
        $this->assertEquals(1, $return_var);
    }
}
于 2015-03-30T23:08:52.973 に答える
3

この関数を単純にモックして、取得しようとしているテキストを $settings に返します。実行可能ファイルを呼び出す必要はなく、単にファイルを作成するか返すだけです。

たとえば、関数 get_setting_values_from_file() が設定を配列として返すと仮定すると、テストで関数を単純にモックして、設定を配列として返すことができます。get_setting_values_from_file() メソッドを含むオブジェクトをモックするテスト スタブを作成し、そのモックがテストで想定したのと同じ FALSE、1 または 2 を返すようにします。

$stub = $this->getMock('GetSettingsClass');
    $stub->expects($this->any())
         ->method('get_settings_from_file')
         ->will($this->returnValue(0));

これは PHPUnit マニュアルからのものです -> http://phpunit.de/manual/3.8/en/test-doubles.html#test-doubles.stubs

必要に応じて、呼び出しをバイパスし、配列を作成してそれらの関数に渡すことで、戻り値で機能する関数/コードをテストすることもできます。メインコードで想定される例:

...
$settings = get_setting_values_from_file( 'UserType' );
$UserType = get_user_type($settings);
return $UserType;

function get_user_type($settings)
{
    if($settings !== FALSE)         // Returned from your function if parameter is not found
    {
        switch($settings)
        {
            case 1:
                return 'User';      // Best to use Constants, but for example here only
                break;
            case 2:
                return 'Admin';
                break;
            ...
         }
    }
    else
    {
        return FALSE;
    }
}

さて、あなたのテストでは、簡単に

$this->assertFalse(get_user_type(FALSE, 'Ensure not found data is handled properly as FALSE is returned');
$this->assertEqual('User', get_user_type(1), 'Test UserType=1');
$this->assertEqual('Admin', get_user_type(1), 'Test UserType=2');
...

これらは、コードが OS からの読み取りをモックする必要があった関数を呼び出さないため機能しますが、設定の戻り値を処理する関数を呼び出すことによって、期待されるすべての戻り値を処理します。ここでは、ファイルやモックを必要とせずに、関数 'get_setting_values_from_file()' からの戻りを単純に想定しています。

ただし、これはファイルからの読み取りをテストするものではありません。別のテストでは、setUp と tearDown を使用して必要な値 (fopen/fwrite) を持つファイルを実際に作成し、関数を呼び出して、期待どおりの値が返されることを確認します。 .

これが私が考えていたことを説明するのに役立つことを願っています.

于 2013-06-27T13:38:40.547 に答える