问题
I'm learning Zend and also PHPUnit.
Here is what I have below
public function changeToIllegalState()
{
return array(
array( Application_Model_SomeModel::FAIL ),
array( Application_Model_SomeModel::SUCCESS )
);
}
/**
* @dataProvider changeToIllegalState
* @expectedException IllegalStateChangeException
*/
public function testIllegalStateChangeGeneratesException( $state )
{
$mapper = new Application_Model_Mapper_SomeModel();
$model = new Application_Model_SomeModel();
$model->changeState( $state );
$mapper->save( $model );
}
So as you can see here, the data provider provides some constants that represent different states from the model.
PHPUnit says that it can't find the Model class in the dataprovider method. However, if I try to use the constants within the test methods, it all works and there are no problems. I'm using the Zend autoloader to load my classes and it has all been dandy up till now. I know that I could just put in the values for the constants themselves, but I don't know why I'm getting this error.
I can only assume that the dataprovider methods are called before the setup method is called because I do all the autoloading business in the setup method.
EDIT :
I have also tried the following but it still won't work with the class consts.
protected $_FAIL;
protected $_model;
public function setUp()
{
parent::setUp();
$this->_model = new Application_Model_SomeModel();
$this->_FAIL = Application_Model_SomeModel::FAIL;
}
Now, when I try to use $_FAIL in the provider method I get a NULL value instead of the 'fail' string that I'm expecting. This is really weird.
回答1:
PHPUnit instantiates all of test cases that will be run before running any tests.
- One per test method without a data provider.
- One per data provider method.
- One per parameter array returned from each data provider, so a provider that returns an array of four arrays gets four test case instances.
Assuming you're setting up the autoloader in your bootstrap.php, it should load the class containing those constants. However, I would try a test to see:
public function changeToIllegalState()
{
require_once 'Zend/Loader/Autoloader';
Zend_Loader_Autoloader::getInstance();
return array(
array( Application_Model_SomeModel::FAIL ),
array( Application_Model_SomeModel::SUCCESS )
);
}
Or is Zend Framework adding the models' directory to the include path in one of the test case's setUp()
method instead?
回答2:
I figured out what is going on, finally.
PHPUnit will call all the dataprovider methods of a class before it calls any of the setup methods, this includes the static method setUpBeforeClass.
I put in a bunch of echo statements in the data provider methods and setUp methods to confirm this. All the provider method echos always printed before setup method echos.
In addition, the echos of provider methods were only echoed when the methods were declared as data providers with the dataprovider annotation. That is to say, any methods not declared as dataprovider methods with the annotation are not called at all.
My initial assumption about PHPUnit calling the provider methods before my setUp method was right.
To fix this, I have to instantiate my Zend_Application object in the bootstrap file instead of in the setUp method. I didn't want to do this because I didn't need the Zend_Application object for all the test cases but I think that this is what I'll end up doing since it'll make my life a little easier.
@David Harkness you were right about setting up the autoloader in the bootstrap in this case but I also needed to setup the application autoloading (by making the Zend_Application object), not just the Zend library autoloading.
来源:https://stackoverflow.com/questions/5561844/phpunit-using-class-consts-to-change-state