PHPUunit 모의 객체 및 정적 방법
다음 정적 방법을 테스트하는 가장 좋은 방법을 찾고 있습니다(특히 독트린 모델 사용).
class Model_User extends Doctrine_Record
{
public static function create($userData)
{
$newUser = new self();
$newUser->fromArray($userData);
$newUser->save();
}
}
이상적으로, 나는 모의 물체를 사용하여 그것을 확실히 할 것입니다.fromArray
(제공된 사용자 데이터 포함) 및save
호출되었지만 메서드가 정적이므로 불가능합니다.
좋은 의견이라도 있나?
PHP 유닛의 저자인 Sebastian Bergmann은 최근 Stubbing과 Mocking Static Methods에 대한 블로그 게시물을 가지고 있습니다.PHPUnit 3.5 및 PHP 5.3을 사용하고 최신 정적 바인딩을 일관되게 사용하면 다음과 같은 작업을 수행할 수 있습니다.
$class::staticExpects($this->any())
->method('helper')
->will($this->returnValue('bar'));
업데이트: staticExpects
는 PHPUit 3.8에서 더 이상 사용되지 않으며 이후 버전에서는 완전히 제거될 예정입니다.
이제 AspectMock 라이브러리를 사용하여 다음 작업을 수행할 수 있습니다.
https://github.com/Codeception/AspectMock
$this->assertEquals('users', UserModel::tableName());
$userModel = test::double('UserModel', ['tableName' => 'my_users']);
$this->assertEquals('my_users', UserModel::tableName());
$userModel->verifyInvoked('tableName');
나는 유닛 테스트 네임스페이스에서 확장된 새로운 클래스를 만들 것입니다.Model_User
그리고 그것을 테스트합니다.다음은 예입니다.
원래 클래스:
class Model_User extends Doctrine_Record
{
public static function create($userData)
{
$newUser = new self();
$newUser->fromArray($userData);
$newUser->save();
}
}
단원 테스트를 호출할 모의 수업:
use \Model_User
class Mock_Model_User extends Model_User
{
/** \PHPUnit\Framework\TestCase */
public static $test;
// This class inherits all the original classes functions.
// However, you can override the methods and use the $test property
// to perform some assertions.
}
단위 테스트에서:
use Module_User;
use PHPUnit\Framework\TestCase;
class Model_UserTest extends TestCase
{
function testCanInitialize()
{
$userDataFixture = []; // Made an assumption user data would be an array.
$sut = new Mock_Model_User::create($userDataFixture); // calls the parent ::create method, so the real thing.
$sut::test = $this; // This is just here to show possibilities.
$this->assertInstanceOf(Model_User::class, $sut);
}
}
작업 솔루션을 찾았습니다. 주제가 오래되었음에도 불구하고 공유하고 싶습니다.class_alias
아직 자동 로드되지 않은 클래스를 대체할 수 있습니다. 파일을 직접 포함/포함하지 않고 자동 로드를 사용하는 경우에만 작동합니다.예를 들어 코드는 다음과 같습니다.
class MyClass
{
public function someAction() {
StaticHelper::staticAction();
}
}
테스트:
class MyClassTest
{
public function __construct() {
// works only if StaticHelper is not autoloaded yet!
class_alias(StaticHelperMock::class, StaticHelper::class);
}
public function test_some_action() {
$sut = new MyClass();
$myClass->someAction();
}
}
우리의 모의:
class StaticHelperMock
{
public static function staticAction() {
// here implement the mock logic, e.g return some pre-defined value, etc
}
}
이 간단한 솔루션에는 특별한 립이나 확장이 필요하지 않습니다.
Mockery의 별칭 기능을 사용하여 공개 정적 메서드를 모의할 수 있습니다.
http://docs.mockery.io/en/latest/reference/creating_test_doubles.html#creating-test-doubles-aliasing
또 다른 가능한 접근 방식은 Moka 라이브러리입니다.
$modelClass = Moka::mockClass('Model_User', [
'fromArray' => null,
'save' => null
]);
$modelClass::create('DATA');
$this->assertEquals(['DATA'], $modelClass::$moka->report('fromArray')[0]);
$this->assertEquals(1, sizeof($modelClass::$moka->report('save')));
한 가지 더 접근 방식:
class Experiment
{
public static function getVariant($userId, $experimentName)
{
$experiment = self::loadExperimentJson($experimentName):
return $userId % 10 > 5; // some sort of bucketing
}
protected static function loadExperimentJson($experimentName)
{
// ... do something
}
}
내 실험 테스트에서.php
class ExperimentTest extends \Experiment
{
public static function loadExperimentJson($experimentName)
{
return "{
"name": "TestExperiment",
"variants": ["a", "b"],
... etc
}"
}
}
그런 다음 이렇게 사용할 것입니다.
public function test_Experiment_getVariantForExperiment()
{
$variant = ExperimentTest::getVariant(123, 'blah');
$this->assertEquals($variant, 'a');
$variant = ExperimentTest::getVariant(124, 'blah');
$this->assertEquals($variant, 'b');
}
정적 방법을 테스트하는 것은 일반적으로 (아마도 이미 알고 있었겠지만) 특히 PHP 5.3 이전에는 좀 어려운 것으로 간주됩니다.
정적 방법을 사용하지 않도록 코드를 수정할 수 없습니까? 사실 여기서 정적 방법을 사용하는 이유를 잘 모르겠습니다. 이것은 아마도 정적이 아닌 코드로 다시 작성될 수도 있습니다. 그렇지 않나요?
예를 들어, 다음과 같은 것이 효과를 발휘하지 못할 수도 있습니다.
class Model_User extends Doctrine_Record
{
public function saveFromArray($userData)
{
$this->fromArray($userData);
$this->save();
}
}
무엇을 테스트할지 확신할 수 없지만, 적어도 더 이상 정적인 방법은 없습니다.
언급URL : https://stackoverflow.com/questions/2357001/phpunit-mock-objects-and-static-methods
'IT' 카테고리의 다른 글
100,000개 이상의 개별 IP 주소를 차단하는 방법 (0) | 2023.07.27 |
---|---|
마리아에서 'DEELETE'에 대해 지정된 Twice 테이블DB (0) | 2023.07.27 |
CSS를 사용하여 텍스트 숨기기 (0) | 2023.07.27 |
Elastic Beanstalk Java 환경에 배포된 Spring Boot 애플리케이션이 502를 반환합니다. (0) | 2023.07.27 |
JSONP 요청이 작동하는 방식에 대해 혼동됨 (0) | 2023.07.27 |