39

次のクラスがあるとします。

<?php
class Example {
    private $Other;

    public function __construct ($Other)
    {
        $this->Other = $Other;
    }

    public function query ()
    {   
        $params = array(
            'key1' => 'Value 1'
            , 'key2' => 'Value 2'
        );

        $this->Other->post($params);
    }
}

そしてこのテストケース:

<?php
require_once 'Example.php';
require_once 'PHPUnit/Framework.php';

class ExampleTest extends PHPUnit_Framework_TestCase {

    public function test_query_key1_value ()
    {   
        $Mock = $this->getMock('Other', array('post'));

        $Mock->expects($this->once())
              ->method('post')
              ->with(YOUR_IDEA_HERE);

        $Example = new Example($Mock);
        $Example->query();
    }

$params(配列である)が渡され$Other->post()、値が「値1」の「key1」という名前のキーが含まれていることを確認するにはどうすればよいですか?

すべての配列を検証したくありません。これは単なるサンプルコードです。実際のコードでは、渡された配列にはさらに多くの値があり、そこにある1つのキーと値のペアだけを検証したいと思います。

$this->arrayHasKey('keyname')キーが存在することを確認するために使用できることがあります。

$this->contains('Value 1')配列にこの値があることを確認するために使用できる、もあります。

これら2つを。と組み合わせることもでき$this->logicalAndます。しかし、これはもちろん望ましい結果をもたらしません。

これまで、returnCallbackを使用して、$ params全体をキャプチャし、それに対してアサートを実行してきましたが、おそらく別の方法でやりたいことを実行できますか?

4

6 に答える 6

53

$this->arrayHasKey('keyname');メソッドは存在しますが、その名前はassertArrayHasKey次のとおりです。

// In your PHPUnit test method
$hi = array(
    'fr' => 'Bonjour',
    'en' => 'Hello'
);

$this->assertArrayHasKey('en', $hi);    // Succeeds
$this->assertArrayHasKey('de', $hi);    // Fails
于 2014-06-05T13:24:36.770 に答える
16

再利用可能な制約クラスを作成する代わりに、PHPUnitの既存のコールバック制約を使用して配列キーの値をアサートすることができました。私のユースケースでは、モックされたメソッドの2番目の引数で配列値をチェックする必要がありました(興味がある場合は、 MongoCollection :: ensureIndex())。これが私が思いついたものです:

$mockedObject->expects($this->once())
    ->method('mockedMethod')
    ->with($this->anything(), $this->callback(function($o) {
        return isset($o['timeout']) && $o['timeout'] === 10000;
    }));

コールバック制約は、コンストラクターで呼び出し可能オブジェクトを予期し、評価中にそれを呼び出すだけです。呼び出し可能オブジェクトがtrueまたはfalseを返すかどうかに基づいて、アサーションは成功または失敗します。

大規模なプロジェクトの場合は、再利用可能な制約を作成するか(上記のソリューションのように)、PR#312をPHPUnitにマージするように要求することをお勧めしますが、これは1回限りの必要性のためのトリックでした。より複雑なアサーションに対しても、コールバック制約がどのように役立つかを簡単に確認できます。

于 2013-02-12T16:40:23.593 に答える
8

属性1に基づいて、独自の制約クラスを作成することになりました。

<?php
class Test_Constraint_ArrayHas extends PHPUnit_Framework_Constraint
{
    protected $arrayKey;

    protected $constraint;

    protected $value;

    /**
     * @param PHPUnit_Framework_Constraint $constraint
     * @param string                       $arrayKey
     */
    public function __construct(PHPUnit_Framework_Constraint $constraint, $arrayKey)
    {
        $this->constraint  = $constraint;
        $this->arrayKey    = $arrayKey;
    }


    /**
     * Evaluates the constraint for parameter $other. Returns TRUE if the
     * constraint is met, FALSE otherwise.
     *
     * @param mixed $other Value or object to evaluate.
     * @return bool
     */
    public function evaluate($other)
    {
        if (!array_key_exists($this->arrayKey, $other)) {
            return false;
        }

        $this->value = $other[$this->arrayKey];

        return $this->constraint->evaluate($other[$this->arrayKey]);
    }

    /**
     * @param   mixed   $other The value passed to evaluate() which failed the
     *                         constraint check.
     * @param   string  $description A string with extra description of what was
     *                               going on while the evaluation failed.
     * @param   boolean $not Flag to indicate negation.
     * @throws  PHPUnit_Framework_ExpectationFailedException
     */
    public function fail($other, $description, $not = FALSE)
    {
        parent::fail($other[$this->arrayKey], $description, $not);
    }


    /**
     * Returns a string representation of the constraint.
     *
     * @return string
     */
    public function toString ()
    {
        return 'the value of key "' . $this->arrayKey . '"(' . $this->value . ') ' .  $this->constraint->toString();
    }


    /**
     * Counts the number of constraint elements.
     *
     * @return integer
     */
    public function count ()
    {
        return count($this->constraint) + 1;
    }


    protected function customFailureDescription ($other, $description, $not)
    {
        return sprintf('Failed asserting that %s.', $this->toString());
    }

次のように使用できます。

 ... ->with(new Test_Constraint_ArrayHas($this->equalTo($value), $key));
于 2009-09-29T08:25:51.240 に答える
3

パラメータに対して複雑なテストを行い、有用なメッセージと比較を行いたい場合は、コールバック内にアサーションを配置するオプションが常にあります。

例えば

$clientMock->expects($this->once())->method('post')->with($this->callback(function($input) {
    $this->assertNotEmpty($input['txn_id']);
    unset($input['txn_id']);
    $this->assertEquals($input, array(
        //...
    ));
    return true;
}));

コールバックがtrueを返すことに注意してください。そうしないと、常に失敗します。

于 2016-02-25T17:27:28.513 に答える
0

キーが存在しない場合(失敗ではなく)にエラーが発生してもかまわない場合は、次を使用できます。

$this->assertEquals('Value 1', $params['key1']);
于 2021-11-10T13:52:31.960 に答える
-4

申し訳ありませんが、私は英語を話しません。

array_key_exists関数を使用して配列にキーが存在するかどうかをテストでき、array_searchを使用して値が存在するかどうかをテストできると思います。

例えば:

function checkKeyAndValueExists($key,$value,$arr){
    return array_key_exists($key, $arr) && array_search($value,$arr)!==false;
}

!==array_searchは、存在する場合はその値のキーを返し、それが0である可能性があるために使用します。

于 2009-09-28T15:51:49.110 に答える