-1

私はこのようなコードを持っています:

protected function _checkUserVisibility()
{
    try {
        if (!$params->getUsrParametr(self::ACTIVE_FIF)) { // calling oracle stored proc
            throw new Unitex_Exception('ALARM');
        }
    }
    catch (Exception $e) {
        $this->logOut();
        throw $e;
    }
}

この関数は別の関数から落ち着きました(など)。

質問:コードのその部分のユニットテストを機能させる方法は?

編集1:

最初にhttp://framework.zend.com/manual/1.12/en/zend.test.phpunit.htmlを取得しました が、改善された(希望の)テスト手順は次のとおりです。

class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase {
..........
public function testLoginAction()
{
    $request = $this->getRequest();
    $request->setMethod('POST')
        ->setHeader('X_REQUESTED_WITH', 'XMLHttpRequest')
        ->setPost(array(
                'user'     => 'test_user',
                'password' => 'test_pwd',
        ));

        $filialId = 1;
        $stmt1 = Zend_Test_DbStatement::createUpdateStatement();
        $this->getAdapter()->appendStatementToStack($stmt1);
        $this->getAdapter()->appendStatementToStack($stmt1);
        $this->getAdapter()->appendStatementToStack($stmt1);
        $this->getAdapter()->appendStatementToStack($stmt1);

        $stmt1Rows = array(array('IRL_ALIAS' => 'RO_COMMON', 'ISADM' => 'N'));
        $stmt1 = Zend_Test_DbStatement::createSelectStatement($stmt1Rows);
        $this->getAdapter()->appendStatementToStack($stmt1);

        $this->dispatch('/user/login');// <-- crash here
    $this->assertController('user');
    $this->assertAction('login');
    $this->assertNotRedirect();
    $this->_getResponseJson();
}
4

2 に答える 2

4

ユニットテストでは、データベースとの相互作用は絶対に必要ありません。あなたの質問に対する答えは、db機能にスタブを使用することです。

$がcontainsparamsのプロパティであり、たとえばデータベースから何かを取得するとします。メソッドをテストしているので、で何が起こっているかは気にしません。そうすれば、テストは次のようになります。SomeClassgetUsrParametr_checkUserVisibilitySomeClass

class YourClass
{
    protected $params;

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

    public function doSomething()
    {
        $this->_checkUserVisibility();
    }

    protected function _checkUserVisibility()
    {
        try {
            if (!$this->params->getUsrParametr(self::ACTIVE_FIF)) { // calling oracle stored proc
                throw new Unitex_Exception('ALARM');
            }
        }
        catch (Exception $e) {
            $this->logOut();
            throw $e;
        }
    }
}

もちろん、単体テストはパブリックメソッドのみですが、パブリックメソッドのテストを通じて保護されたメソッドをカバーします。

public function testDoSomethingAlarm()
{
    // set expected exception:
    $this->setExpectedException('Unitex_Exception', 'ALARM');

    // create the stub
    $params = $this->getMock('SomeClass', array('getUsrParametr'));

    // and set desired result
    $params->expects($this->any())
        ->method('getUsrParametr')
        ->will($this->returnValue(false));

    $yourClass = new YourClass($params);
    $yourClass->doSomething();
}

そして、テストケースgetUsrParametrが返す2番目のテストtrue

public function testDoSomethingLogout()
{
    // set expected exception:
    $this->setExpectedException('SomeOtherException');

    // create the stub
    $params = $this->getMock('SomeClass', array('getUsrParametr'));

    // set throw desired exception to test logout
    $params->expects($this->any())
        ->method('getUsrParametr')
        ->will($this->throwException('SomeOtherException'));

    // now you want create mock instead of real object beacuse you want check if your class will call logout method:   
    $yourClass = $this->getMockBuilder('YourClass')
        ->setMethods(array('logOut'))
        ->setConstructorArgs(array($params))
        ->getMock();

    // now you want ensure that logOut will be called
    $yourClass->expects($this->once())
        ->method('logOut');

    // pay attention that you've mocked only logOut method, so doSomething is real one
    $yourClass->doSomething();
}
于 2012-12-15T12:10:05.090 に答える
2

PHPUnitでPHP5.3.2+を使用している場合は、リフレクションを使用してプライベートメソッドとプロテクトメソッドをテストし、テストを実行する前にパブリックに設定できます。それ以外の場合は、パブリックメソッドを適切にテストしてプロテクト/プライベートメソッドをテストします。保護された/プライベートな方法を使用します。一般的に言えば、2つのオプションの後半は、一般的にどのように行うべきかですが、リフレクションを使用する場合は、一般的な例を次に示します。

protected static function getMethod($name) {
  $class = new ReflectionClass('MyClass');
  $method = $class->getMethod($name);
  $method->setAccessible(true);
  return $method;
}

public function testFoo() {
  $foo = self::getMethod('foo');
  $obj = new MyClass();
  $foo->invokeArgs($obj, array(...));
  ...
}
于 2012-12-14T02:56:41.050 に答える