Question

Compte tenu de la classe suivante:

<?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);
    }
}

Et ce testcase:

<?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();
    }

Comment puis-je vérifier que $params (qui est un tableau) et est passé à $Other->post() contient une clé nommée « key1 » qui a une valeur de « valeur 1 »?

Je ne veux pas vérifier tous le tableau - c'est juste un exemple de code, dans le code réel du tableau passé a beaucoup plus de valeurs, je veux vérifier une seule paire clé / valeur là-dedans

Il est $this->arrayHasKey('keyname') que je peux utiliser pour vérifier que la clé existe.

Il est également $this->contains('Value 1'), qui peut être utilisé pour vérifier que le tableau a cette valeur.

Je pourrais même combiner les deux avec $this->logicalAnd. Mais cela bien sûr ne donne pas le résultat souhaité.

Jusqu'à présent, j'utilise returnCallback, capturant l'ensemble $ params et faire ensuite ce affirme, mais est-il peut-être une autre façon de faire ce que je veux?

Était-ce utile?

La solution 3

J'ai fini par créer ma propre classe de contrainte, en fonction de l'attribut un

<?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());
    }

Il peut être utilisé comme ceci:

 ... ->with(new Test_Constraint_ArrayHas($this->equalTo($value), $key));

Autres conseils

La méthode $this->arrayHasKey('keyname'); existe, mais son nom est assertArrayHasKey:

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

$this->assertArrayHasKey('en', $hi);    // Succeeds
$this->assertArrayHasKey('de', $hi);    // Fails

Au lieu de créer une classe de contrainte réutilisable, je suis en mesure d'affirmer la valeur d'un tableau clé en utilisant la contrainte de rappel existant dans PHPUnit. Dans mon cas d'utilisation, je avais besoin pour vérifier une valeur de tableau dans le second argument à une méthode moqué ( MongoCollection :: ensureIndex () , si quelqu'un est curieux). Voici ce que je suis venu avec:

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

La href="https://github.com/sebastianbergmann/phpunit/blob/master/PHPUnit/Framework/Constraint/Callback.php" attend callable dans son constructeur, et appelle simplement lors de l'évaluation. L'affirmation passe ou échoue sur la base du fait que les déclarations appelables vrai ou faux.

Pour un grand projet, je recommanderais certainement créer une contrainte réutilisable (comme dans la solution ci-dessus) ou pour une pétition PR # 312 à fusionner en PHPUnit, mais cela a fait l'affaire pour un besoin ponctuel. Il est facile de voir comment la contrainte de rappel peut être utile pour des assertions plus complexes aussi.

Dans le cas où vous souhaitez faire des tests complexes sur le paramètre, et ont également des messages et des comparaisons utiles, il y a toujours la possibilité de placer des affirmations dans le rappel.

par exemple.

$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;
}));

Notez que le rappel retourne vrai. Dans le cas contraire, il échouera toujours.

Désolé, je ne suis pas anglophone.

Je pense que vous pouvez tester si une clé existe dans le tableau avec la fonction array_key_exists, et vous pouvez tester si la valeur existe avec array_search

Par exemple:

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

Utilisez !== parce array_search remettre la clé de cette valeur si existe et il peut être 0.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top