首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用PHP编写接口测试

如何用PHP编写接口测试
EN

Stack Overflow用户
提问于 2015-03-20 10:51:50
回答 2查看 2.9K关注 0票数 2

如果我正在编写一个接口,我通常会指定实现应该公开的行为。为了确保这种行为,我们应该针对这个接口编写测试。我如何最好地编写和组织这些测试,以便实现的编写人员能够很容易地使用它们,以确保它们的实现满足需求?是否有某种方式扩展(编写子类)接口测试的方式,或我是否实现了一些设计模式,如工厂?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-20 11:32:25

您可以使用接口契约的一些基本测试创建一个抽象类。

考虑以下例子:

代码语言:javascript
复制
interface FactorialComputer {
    public function compute($input);
}

class RecursiveFactorialComputer implements FactorialComputer  {
    public function compute($input) {
        if ($input < 0) {
            throw new InvalidArgumentException(...);
        }

        if ($input == 0 || $input == 1) {
            return 1;
        }

        return $input * $this->compute($input - 1);
    }
}

class IterativeFactorialComputer implements FactorialComputer  {
    public function compute($input) {
        $result = 1;

        for ($i = 1; $i <= $input; $i++) {
            $result *= $i;
        }

        return $result;
    }
}

和对这两种实现的测试:

代码语言:javascript
复制
abstract class AbstractFactorialComputerTest extends PHPUnit_Framework_TestCase {
    /**
     * @var FactorialComputer 
     */
    protected $instance;

    protected abstract function getComputerInstance();

    public function setUp() {
        $this->instance = $this->getComputerInstance;
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testExceptionOnInvalidArgument() {
        $this->instance->compute(-1);
    }

    public function testEdgeCases()
    {
        $this->assertEquals(1, $this->instance->compute(0));
        $this->assertEquals(1, $this->instance->compute(1));
    }

    ...
}

class RecursiveFactorialComputerTest extends AbstractFactorialComputerTest
{
    protected abstract function getComputerInstance() {
        return new RecursiveFactorialComputer();
    }

    public function testComputeMethodCallsCount() {
        // get mock and test number of compute() calls
    }
}

class IterativeFactorialComputerTest extends AbstractFactorialComputerTest
{
    protected abstract function getComputerInstance() {
        return new IterativeFactorialComputer();
    }
}

使用这种方法,每个程序员都应该能够为接口实现创建完整的单元测试。

票数 2
EN

Stack Overflow用户

发布于 2015-03-20 11:15:01

我明白为什么人们告诉你你不需要测试接口。但这不是你想要的。您要求为实现特定接口的多个类执行相同单元测试的更简单的方法。我使用@dataProvider注释来实现这一点(PHPUnit,是的)。

让我们假设您有以下类:

代码语言:javascript
复制
interface Shape {
    public function getNumberOfSides();
}

class Triangle implements Shape {
    private $sides = 3;
    
    public function getNumberOfSides() {
        return $this->sides;
    }
}

class Square implements Shape {
    private $sides = 4;
    
    public function getNumberOfSides() {
        return $this->sides;
    }
}

现在要测试Triangle getNumberOfSides的实例是否定义并返回3,而对于Square则返回4。

代码语言:javascript
复制
class ShapeTest extends PHPUnit_Framework_TestCase {

    /**
     * @dataProvider numberOfSidesDataProvider
     */
    public function testNumberOfSides(Shape $shape, $expectedSides){
        $this->assertEquals($shape->getNumberOfSides(), $expectedSides);
    }
    
    public function numberOfSidesDataProvider() {
        return array(
            array(new Square(), 5),
            array(new Triangle(), 3)
        );
    }
}

在这里运行phpunit将产生预期的输出:

代码语言:javascript
复制
There was 1 failure:

1) ShapeTest::testNumberOfSides with data set #0 (Square Object (...), 5)
Failed asserting that 5 matches expected 4.

/tests/ShapeTest.php:12

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29164814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档