125*_*369 14 php phpunit unit-testing
刚刚跳进PHPUnit,一直在阅读有关它的内容,尝试一些例子,以便为我未来的项目编写测试.
我需要测试这个场景,我有Student Class,它是这样的:
class Students
{
public function getStudents($studentName, $studentId)
{
$students= array();
//Instantiating OldStudent Class from Old Project
$oldStudents = \OldStudents::getStudentByName($studentName, $studentId);
//Create a Student Object for every OldStudent found on Old Project and set
//values
foreach ($oldStudents as $oldStudent)
{
$student = new \Entity\Student();
//Set Student ID
$student->setStudentId($oldStudent->getStudentID());
//Set Student Name
$student->setStudentName($oldStudent->getStudentName());
//.....other setters for student data, irrelevant for this example
$students[] = $student;
}
return $students;
}
}
Run Code Online (Sandbox Code Playgroud)
和学生班
Class Student
{
protected $studentId;
protected $studentName;
public function getStudentId()
{
return $this->studentId;
}
public function setStudentId($studentId)
{
$this->studentId = $studentId;
return $this;
}
public function getStudentName()
{
return $this->studentName;
}
public function setStudentName($studentName)
{
$this->studentName = $studentName;
return $this;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我如何测试Students Class 是否返回一组具有设置值的对象,并使用Student Class中的getter检查值
请抛出一些灯光/信息/链接,无论哪个指引我在正确的路径.
谢谢
Dar*_*ook 33
我在下面写了一些示例代码; 我猜测参数getStudents
是可选的过滤器.我们有一个测试可以吸引所有学生.我不知道他们是否总是以排序的顺序返回,这就是为什么我不在Student课程中测试任何其他内容的原因.第二个测试得到一个特定的学生,并开始测试一些学生属性.
class StudentsTest extends PHPUnit_Framework_TestCase{
public function testGetAllStudents(){
$s=new Students;
$students=$s->getStudents("","");
$this->assertIsArray($students);
$this->assertEquals(7,count($students));
$first=$students[0]; //Previous assert tells us this is safe
$this->assertInstanceOf('Student',$first);
}
public function testGetOnlyStudentNamedBob(){
$s=new Students;
$students=$s->getStudents("Bob","");
$this->assertIsArray($students);
$this->assertEquals(1,count($students));
$first=$students[0]; //Previous assert tells us this is safe
$this->assertInstanceOf('Student',$first);
$this->assertEquals('Bob',$first->getStudentName());
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个很好的第一步.使用它一段时间后,你会发现它非常脆弱.即你必须有7名学生才能通过第一次测试.必须有一个叫鲍勃的学生才能通过.如果您\OldStudents::getStudentByName
从数据库获取数据,它也会很慢; 我们希望单元测试尽可能快地运行.
两者的解决方法是模拟调用\OldStudents::getStudentByName
.然后你可以注入你自己的人工数据,然后你只会测试逻辑getAllStudents
.这反过来又意味着当您的单元测试中断时,只有20行左右可以打破它,而不是1000秒.
究竟如何进行模拟是一个完整的问题,可能依赖于PHP版本,以及代码设置的灵活性.("OldStudents"听起来像是在处理遗留代码,也许你无法触及它.)
Sve*_*ven 24
自3.1.4版以来PHPUnit的断言"assertContainsOnly"带有参数"type",它可以断言任何PHP类型(包括实例和内部类型),并且至少版本3.7中有断言"assertContainsOnlyInstancesOf",它只显示类检查实例,而不是PHP变量类型.
因此测试检查数组是否只包含给定类型的对象只是:
$this->assertContainsOnlyInstancesOf('Student', $students);
Run Code Online (Sandbox Code Playgroud)
请注意,此检查隐式测试$students
是实现Traversable接口的数组还是对象.实现Traversable并不意味着你可以计数,因此assertCount
事后调用断言给定数量的Student
对象并不能保证成功,但是实际上返回值是一个数组的额外检查对我来说似乎太过臃肿.您正在创建并返回包含其中某些内容的数组 - 可以安全地假设您可以计算它.但到处都不是这种情况.
你可以用断言来做到这一点。首先你应该得到一个实际的结果,然后用它做一些断言。相比:
你可以断言它是一个数组:
class InternalTypeTest extends PHPUnit_Framework_TestCase
{
public function testFailure()
{
$this->assertInternalType('array', 42);
# Phpunit 7.5+: $this->assertIsArray(42);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以断言它不是空的(你知道它必须返回一些数据):
class NotEmptyTest extends PHPUnit_Framework_TestCase
{
public function testFailure()
{
$this->assertNotEmpty(ARRAY());
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以断言每个值都是你的学生类型:
class InstanceOfTest extends PHPUnit_Framework_TestCase
{
public function testFailure()
{
$this->assertInstanceOf('Student', new Exception);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这能给你一些提示。有关常见断言的列表,请参阅上面的链接。如果您使用 IDE 来编写测试,它也应该提供所有断言的列表。
归档时间: |
|
查看次数: |
45125 次 |
最近记录: |