2

Michelangelo van Dam aka DragonBe によるPHP プロジェクトの品質保証に関する素晴らしいプレゼンテーションを読んでいたところです。彼のプレゼンテーションでは、私が基本的なレベルでよく知っている Zend-Framework を例として使用しています。

私は自分自身を改善したいので、単体テストから始めますが、問題はZF側にあると感じています.

問題:

falseZend_Filter または Zend_Validatorのブール値を割り当てるたびに、指定されたコード アーティファクトを使用して、これを に変更しnullます。なぜそうなのかわかりません。

新しいコードとテストについては、下部の更新を参照してください

最初のテスト

public function goodData() {
  return array(
    array('DU-IT', 'Sample Description', true, false),
    array('Mercüß', 'bla"ß"trager', false, true),
    array('Mia123', '728 Tage im Jahr', false, false)
  );
}

/**
 * @dataProvider goodData()
 */
public function testModelAcceptsValidData($name, $description, $flag_active, $flag_deleted)
{
  $data = array(
    'id'            => 0,
    'name'          => $name,
    'description'   => $description,
    'flag_active'   => $flag_active,
    'flag_deleted'  => $flag_deleted
  );

  try {
    $this->_model->populate($data);
  } catch (Zend_Exception $e) {
    $this->fail('Unexpected Exception: '.$e->getMessage());
  }

  $this->assertSame($data, $this->_model->toArray());
}

モデル

public function __construct($props = null)
{
  // Set Filters
  $this->_filters = array(
    'id'            => array('Int'),
    'name'          => array('StringTrim', 'StripTags'),
    'description'   => array('StringTrim', 'StripTags'),
    'flag_active'   => array(new Zend_Filter_Boolean()),
    'flag_deleted'  => array(new Zend_Filter_Boolean())
  );

  // Set Validators
  $this->_validators = array(
    'id'            => array('Int'),
    'name'          => array(new Zend_Validate_StringLength(array('min'=>4, 'max'=>50))),
    'description'   => array(new Zend_Validate_StringLength(array('max'=>5000))),
    'flag_active'   => array(new Zend_Validate_InArray(array(true, false))),
    'flag_deleted'  => array(new Zend_Validate_InArray(array(true, false)))
  );

  // Set Properties
  if (!is_null($props)) {
    $this->populate($props);
  }
}

public function setFlagActive($arg)
{
  $input = new Zend_Filter_Input($this->_filters, $this->_validators);
  $input->setData(array('flag_active'=>$arg));
  if (!$input->isValid('flag_active')) {
    throw new Zend_Exception('Invalid FLAG_ACTIVE provided'. gettype($input->flag_active));
  }
  $this->_flag_active = (bool) $input->flag_active;
  return $this;
}

モデルに関する限り、バリデーターを空のままにしてみましflag_activeflag_deletedが、結果は変わりませんでした。phpunit のエラー メッセージは同じままです。

Unexpected Exception: Invalid FLAG_ACTIVE providedNULL

NULL は変数の型ですが、WHENEVER ifalseはデータ プロバイダー goodData() を介してフラグの引数として渡します (badData でも同じことが起こります)。

私の推測では、これは Zend_Filter と関係がありますが、これを理解することはできません。そしてヒントは大歓迎です!

更新 ドリューが少しヒントをくれたので、もう少しテストしましたが、問題は残っています。読みやすくするために、更新されたクラスと単体テストをペーストビンに貼り付けました。

PHPUnit は次のエラーを出します: You must give a non-empty value for field 'flag_active'flag_deleted と同じです。テストの半分での 2 番目のエラーは です<null> does not match expected type "boolean"。私は立ち往生しています。フィルターを使用しても inArrayValidator(array(0=>true,1=>false)) を使用しても、何も変わりません:\

4

1 に答える 1

3

の内容を調べると、$input->getMessages()その特定の値が無効である理由について何らかの説明が得られるはずです。

を使用するZend_Filter_Inputと、検証に合格しなかった値は、魔法のようにその名前でアクセスできなくなります (例: $input->flag_active)。NULL検証ステップに合格しなかった場合、値は常に になります。

フィルターはデータをフィルタリングし、バリデーターに有効な値を返すため、特定のフィルターは、場合によっては検証をほぼ保証できます (つまり、Int バリデーターを使用した Int フィルター)。フィルターを通過helloすると、元の入力データが有効でない場合でも、単純なバリデーターで検証できる戻り値が返されます。Int0Int

例外内で null 値を取得する可能性が最も高い理由は、値が検証されていないために値が利用できないためです。したがって、入力メッセージを調べて、理由に関するヒントを確認してください。

編集:

あなたが抱えている問題はZend_Filter_Input、デフォルトで空の値を許可していないことだと思います。したがって、フィルタに入る値がfalseまたはの場合、フィルタNULLでエラーが発生しています。

このコードをチェックしてください:

    <?php

    // set up a boolean validator and inarray validator like you have
    $filters    = array('test' => array(new Zend_Filter_Boolean()));
    $validators = array('test' => array(new Zend_Validate_InArray(array(true, false))));

    // set up the input filter with default options
    $input      = new Zend_Filter_Input($filters, $validators);

    // our "input" value which is (bool)false
    $test       = false;

    $input->setData(array('test' => $test));

    // run through input filter using default values
    // should throw error about a non-empty value
    if (!$input->isValid('test')) {
        echo "Test is not valid.  <br />Original Value: ";
        var_dump($test);
        echo "<br />";
        print_r($input->getMessages());
    } else {
        echo "Test is valid.<br />Original Value: ";
        var_dump($test);
        echo "<br />Value now: ";
        var_dump($input->test);
    }

    // now allowing empty values...
    echo "<hr />\n";

    // tell Zend_Filter_Input to allow empty values on input
    $options = array(Zend_Filter_Input::ALLOW_EMPTY => true);

    // set up new input filter with option
    $input   = new Zend_Filter_Input($filters, $validators, null, $options);

    $input->setData(array('test' => $test));

    // run through input filter allowing empty values
    // this should NOT throw an error
    if (!$input->isValid('test')) {
        echo "Test is not valid.  <br />Original Value: ";
        var_dump($test);
        echo "<br />";
        print_r($input->getMessages());
    } else {
        echo "Test is valid.<br />Original Value: ";
        var_dump($test);
        echo "<br />Value now: ";
        var_dump($input->test);
    }

したがって、問題は、オプションを指定しない限り、Zend_Filter_Input が空の値を好まないことにあるようです。falseしたがって、有効な ( ) 値をフィルターに送信すると、 に設定Zend_Filter_Input::ALLOW_EMPTYしない限りエラーが発生しますtrue

于 2012-06-25T20:11:46.583 に答える