英文:
PHP Unittest class that loads another class
问题
我有以下情况
class User
{
private $id;
private $roleId;
private $role;
public function __construct(int $id, int $roleId)
{
$this->id = $id;
$this->setRoleId($roleId);
}
public function setRoleId(int $roleId)
{
$this->role = Role::load($roleId);
}
}
class Role
{
public function __construct($x, $y ,$z)
{
//...
}
static function load(int $id) : Role
{
// 一些魔法代码
return new Role($id);
}
public function getRoleId() : int
{
return $this->role->getId();
}
public function getRole() : Role
{
return $this->role;
}
}
我的问题是,如何对User
类进行单元测试?
Role
类从Web服务中加载自身... 一个存根或模拟对象似乎不合适(我猜),因为要模拟的对象是Role
,而我正在测试User
类...
任何想法都欢迎
/BR
Philippe
英文:
I have the following situation
class User
{
private $id;
private $roleId;
private $role;
public function __construct(int $id, int $roleId)
{
$this->id = $id;
$this->setRoleId($roleId);
}
public function setRoleId(int $roleId)
{
$this->role = Role::load($roleId);
}
}
class Role
{
public function __construct($x, $y ,$z)
{
//...
}
static function load(int $id) : Role
{
// some magic code
return new Role($id);
}
public function getRoleId() : int
{
return $this->role->getId();
}
public function getRole() : Role
{
return $this->role;
}
}
My Problem is, how can I unittest the User
-Class?
The Role Class loads itself from a webservice... A Stub or Mock is not suitable (I guess) because, the to-be-mocked-object is Role
and I'm testing the User
-Class here...
Any Idea is welcome
/BR
Philippe
答案1
得分: 0
Your User
class here doesn't do anything except it loads Role. So the question is what would you unit test in this class?
Unit test purpose is to check if one method works as it should. It means if for defined inputs it returns expected results, or throw errors if inputs are not valid.
Stub or mock Role
class is completely OK if you do unit testing. Imagine that you have the next method in User
class (pseudo code I am not so good in PHP)
public function getUserRights() : String[]
{
String[] array = new String[5];
if ($this->role.equals('ADMIN')){
... some logic here ...
}
return array;
}
If now you stub your role and in different tests you return different Role from stubbed (mocked) object you can check that your method getUserRights()
works properly based on different Roles.
And also it is OK to load Role from a webservice but in that case I would call that Integration tests and in that case you want to check if your webservice works correctly and setting those kinds of tests is not as easy as it is to do with unit tests.
英文:
Your User
class here doesn't do anything except it loads Role. So the question is what would you unitest in this class?
Unit test purpose is to check if one method works as it should. It means if for defined inputs it returns expected results, or throw errors if inputs are not valid.
Stub or mock Role
class is completely OK if you do unit testing. Imagine that you have next method in User
class(pseudo code I am not so good in PHP)
public function getUserRights() : String[]
{
String[] array = new String[5];
if ($this->role.equals('ADMIN'){
.... some logic here ...
}
return array;
}
If now you stub your role and in different tests you return different Role from stubbed(mocked) object you can check that your method getUserRights()
works properly based on different Roles.
And also it is OK to loads Role from a webservice but in that case I would call that Integration tests and in that case you want to check if your webservice works correctly and setting those kind of tests is not as easy as it is to do with unit test.
答案2
得分: 0
在这种情况下,您正在让您的 User
类负责加载角色。通常,这不是 User
类的责任。相反,您可以在 User
类上定义一个名为 setRole(Role $role)
的函数,该函数接受一个真实的 Role
或者一个虚假/存根/模拟/任何 Role
,而不是用户ID。然后,角色的检索是在实际使用用户对象的函数/代码中完成的。
但是,如何测试该类?
在单元测试中,通常最好不依赖于像 Role::load
这样的静态方法。相反,您可以使用非静态方法。然后,您可以编写一个扩展 Role
的类,在测试期间执行您想要的操作。然后,您还可以编写一些代码来检查是否已完成您告诉它要做的事情。
这就是为什么通常不建议使用许多静态方法:因为它们难以进行测试。
英文:
In this case you are making your User
class responsible for loading the role. Typically that is not the responsibility of your User
class. Instead, you could for example define a function setRole(Role $role)
on your User
class that accepts either a real Role
, or a fake/stub/mock/whatever Role
, instead of a user ID. The retrieving of the role is then done in the function/code that actually uses the user object.
But then how to test that class?
In unit testing it is usually easier not to depend on static methods like your Role::load
one. Instead you could have a non-static method. Then you could write a class that extends Role
, that does something that you want it to do during your tests. Then you can also write something that checks if what you told it to do was done.
That's why it is often discouraged to use many static methods: because it's hard to test (with) them.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论