dry18813 2016-10-15 16:07
浏览 11

针对PHPUnit中的几个特征测试类

I am testing my Validator php class. The class gets its validator methods as trait. So there is Validator.php file in the src folder and there is validatorMethods.php and ValidatorTest.php file in the test folder.

I would like to test the Validator class with some different validatorMethods.php files so different traits of validator methods would be loaded or do anything else to provide some several traits of validator methods to test the Validator class against those methods.

I thought about sth like putting traits to array and then injecting traits to the Validator class in loop. But it was rather not way to inject traits into object...

So how to test class against various traits? Perhaps better would be to use objects that each uses different trait?

  • 写回答

1条回答 默认 最新

  • douruocai4111 2016-10-20 18:49
    关注

    If I understand you correctly, you have a Validator class that you want to dynamically implement different traits with. This isn't what traits were designed for.

    Traits are for sharing common functionality across different classes without requiring them to extend the same class. Rather what you want to do is make each of your traits a stand-alone class that implements an interface. That you can then pass to your Validator class.

    This would look like this:

    interface ValidatorMethod {
        public function validate($input);
    }
    
    class NumberValidator implements ValidatorMethod {
        public function validate($input) {
            return is_numeric($input);
        }
    }
    
    class IntegerValidator implements ValidatorMethod {
        public function validate($input) {
            return is_integer($input);
        }
    }
    
    class Validator {
        private $validators = [];
    
        public function addValidator (ValidatorMethod $method) {
            $validators[] = $method;
        }
    
        public function validate($input) {
           foreach ($validators as $validator) {
               if (!$validator->validate($input)) {
                   return false;
               }
           }
           return true;
        }
    }
    

    In this case, you would write individual tests for each of the ValidatorMethod objects to verify that they pass correctly. As for the Validator class, you would write tests passing in mock ValidatorMethod that would pass and fail as needed. For example, if you wanted to have all the validators run regardless of the pass/fail of previous ones.

    The tests would look something like so:

    class ExampleValidatorMethodTest {
        public function testValidatePass() {
            $method = new NumberValidator();
            $this->assertTrue($method->validate(1));
        }
    }
    
    class ValidatorTest {
        public function testSingleMethod() {
            $method = $this->getMockBuilder('ValidatorMethod')
                ->getMock();
    
            $input = 'foo';
    
            $method->expects($this->once())
                ->with($input);
                ->will($this->returnValue(True));
    
            $validator = new Validator();
            $validator->addValidator($method);
    
            $this->assertTrue($validator->validate($input));
        }
    
        public function testMultipleMethods() {
            $method1 = $this->getMockBuilder('ValidatorMethod')
                ->getMock();
    
            $method2 = $this->getMockBuilder('ValidatorMethod')
                ->getMock();
    
            $input = 'foo';
    
            $method1->expects($this->once())
                ->with($input);
                ->will($this->returnValue(True));
    
            $method2->expects($this->once())
                ->with($input);
                ->will($this->returnValue(True));
    
            $validator = new Validator();
            $validator->addValidator($method1);
            $validator->addValidator($method2);
    
            $this->assertTrue($validator->validate($input));
        }
    }
    

    There are some optimizations that can be done in the tests to make the code simpler but the examples are to just give an idea of what you are looking to do.

    评论

报告相同问题?

悬赏问题

  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染