2019-02-14 12:12:40 +01:00
|
|
|
Feature: TestCase
|
|
|
|
In order to have typed TestCases
|
|
|
|
As a Psalm user
|
|
|
|
I need Psalm to typecheck my test cases
|
|
|
|
|
|
|
|
Background:
|
|
|
|
Given I have the following code preamble
|
|
|
|
"""
|
|
|
|
<?php
|
2019-02-17 07:28:22 +01:00
|
|
|
namespace NS;
|
2019-02-14 12:12:40 +01:00
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Scenario: TestCase::expectException() rejects non-throwables
|
2019-02-14 12:48:46 +01:00
|
|
|
Given I have Psalm newer than "3.0.12" (because of "missing functionality")
|
2019-02-14 12:12:40 +01:00
|
|
|
Given I have the following code
|
|
|
|
"""
|
|
|
|
class MyTestCase extends TestCase
|
|
|
|
{
|
|
|
|
/** @return void */
|
|
|
|
public function testSomething() {
|
|
|
|
$this->expectException(MyTestCase::class);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
When I run Psalm
|
|
|
|
Then I see these errors
|
2019-02-17 07:28:22 +01:00
|
|
|
| Type | Message |
|
|
|
|
| InvalidArgument | Argument 1 of PHPUnit\Framework\TestCase::expectException expects class-string<Throwable>, NS\MyTestCase::class provided |
|
2019-02-14 12:12:40 +01:00
|
|
|
|
|
|
|
Scenario: TestCase::expectException() accepts throwables
|
|
|
|
Given I have the following code
|
|
|
|
"""
|
|
|
|
class MyTestCase extends TestCase
|
|
|
|
{
|
|
|
|
/** @return void */
|
|
|
|
public function testSomething() {
|
|
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
When I run Psalm
|
|
|
|
Then I see no errors
|
2019-02-17 07:28:22 +01:00
|
|
|
|
|
|
|
Scenario: Stateful test case with setUp produces no MissingConstructor
|
|
|
|
Given I have the following code
|
|
|
|
"""
|
|
|
|
use Prophecy\Prophecy\ObjectProphecy;
|
|
|
|
|
|
|
|
interface I { public function work(): int; }
|
|
|
|
|
|
|
|
class MyTestCase extends TestCase
|
|
|
|
{
|
|
|
|
/** @var ObjectProphecy<I> */
|
|
|
|
private $i;
|
|
|
|
|
|
|
|
public function setUp(): void {
|
|
|
|
$this->i = $this->prophesize(I::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSomething(): void {
|
|
|
|
$this->i->work()->willReturn(1);;
|
|
|
|
$i = $this->i->reveal();
|
|
|
|
$this->assertEquals(1, $i->work());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
When I run Psalm
|
|
|
|
Then I see no errors
|
|
|
|
|
|
|
|
Scenario: Stateful test case with @before produces no MissingConstructor
|
|
|
|
Given I have the following code
|
|
|
|
"""
|
|
|
|
use Prophecy\Prophecy\ObjectProphecy;
|
|
|
|
|
|
|
|
interface I { public function work(): int; }
|
|
|
|
|
|
|
|
class MyTestCase extends TestCase
|
|
|
|
{
|
|
|
|
/** @var ObjectProphecy<I> */
|
|
|
|
private $i;
|
|
|
|
|
|
|
|
/** @before */
|
|
|
|
public function myInit(): void {
|
|
|
|
$this->i = $this->prophesize(I::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSomething(): void {
|
|
|
|
$this->i->work()->willReturn(1);;
|
|
|
|
$i = $this->i->reveal();
|
|
|
|
$this->assertEquals(1, $i->work());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
When I run Psalm
|
|
|
|
Then I see no errors
|
|
|
|
|
|
|
|
Scenario: Stateful test case without @before or setUp produces MissingConstructor
|
|
|
|
Given I have the following code
|
|
|
|
"""
|
|
|
|
use Prophecy\Prophecy\ObjectProphecy;
|
|
|
|
|
|
|
|
interface I { public function work(): int; }
|
|
|
|
|
|
|
|
class MyTestCase extends TestCase
|
|
|
|
{
|
|
|
|
/** @var ObjectProphecy<I> */
|
|
|
|
private $i;
|
|
|
|
|
|
|
|
public function myInit(): void {
|
|
|
|
$this->i = $this->prophesize(I::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testSomething(): void {
|
|
|
|
$this->i->work()->willReturn(1);;
|
|
|
|
$i = $this->i->reveal();
|
|
|
|
$this->assertEquals(1, $i->work());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
When I run Psalm
|
|
|
|
Then I see these errors
|
|
|
|
| Type | Message |
|
|
|
|
| MissingConstructor | NS\MyTestCase has an uninitialized variable $this->i, but no constructor |
|
|
|
|
|