在单元测试期间根据实体的 ID 比较实体
Compare entities based on their ID during unit test
我正在尝试为我的应用程序创建单元测试,但我想得到一些建议。
我有这些方法:
/**
* This methods check if the user can apply to the team, it search if he have a username for the game and if he doesn't already applied for another team in the same tournament
* @param User $user
* @param Team $team
* @return bool|string
*/
public function canApply(User $user, Team $team) {
if ($user->getGamingUsername($team->getTournament()->getGame()) === null) {
return "Vous devez avoir un nom d'utilisateur pour pouvoir vous inscrire, renseignez le dans \"Mon profil\"";
} else if (false !== $teamAlreadyIn = $this->isAlreadyApplicant($user, $team)) {
return "Vous avez déjà postulé pour une équipe pour ce tournoi :
<a href=\"".$this->router->generate("mgd_team_show", array("id" => $teamAlreadyIn->getId()))."\">".htmlspecialchars($teamAlreadyIn->getName())."</a>";
}
return true;
}
/**
* This method search if the user is already in a team for the same tournament than the one passed in argument
* @param User $user
* @param Team $team
* @return bool|Team|mixed
*/
public function isAlreadyApplicant($user, Team $team) {
if (!$user || !$this->authorizationChecker->isGranted("ROLE_USER")) {
return false;
}
foreach ($user->getApplications() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getTeams() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getManagedTeam() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
return false;
}
如您所见,第一个 (canApply) 调用第二个 (isAlreadyApplicant)。
但是当我尝试测试 canApply 时,我遇到了一些麻烦:这个方法调用 isAlreadyApplicant 并且在这个方法中我根据锦标赛的 id 进行比较。
在我的测试中 class,我不能“->setId()”,因为它是一个私有方法。那么我该如何处理呢?
从我的数据库中获取元素是否更好?
目前,我的测试方法之一如下所示:
/**
* The user is connected and try to apply to a team and applied for another team for another game
*/
public function testCanApplySecondTeamAnotherGame() {
$user = new User();
$game = new Game();
$anotherGame = new Game();
$team = new Team();
$anotherTeam = new Team();
$tournament = new TournamentTeam();
$anotherTournament = new TournamentTeam();
$team->setTournament($tournament);
$anotherTeam->setTournament($anotherTournament);
$tournament->setGame($game);
$anotherTournament->setGame($anotherGame);
$game->setName("TestGame");
$anotherGame->setName("AnotherGame");
$gamingProfile = new GamingProfile();
$gamingProfile->setGame($game);
$gamingProfile->setUsername("TestGameUsername");
$anotherGamingProfile = new GamingProfile();
$anotherGamingProfile->setGame($anotherGame);
$anotherGamingProfile->setUsername("TestAnotherGameUsername");
$user->setGamingProfiles(new ArrayCollection(array($gamingProfile, $anotherGamingProfile)));
$user->addApplication($anotherTeam);
$user->addTeam($anotherTeam);
$router = $this->createMock(Router::class);
$authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
$authorizationChecker->method("isGranted")->willReturn(true);
$applicationChecker = new ApplicationChecker($router, $authorizationChecker);
//Here, we try to apply to a team
$this->assertTrue($applicationChecker->canApply($user, $team));
}
如果您有任何问题,请不要犹豫!
祝你有个美好的一天!
这段代码比较耦合,很难用简单的方法进行测试。
我建议你采用方法 isAlreadyApplicant
并以服务为例。
在依赖注入之后,将新服务注入到您的实际服务中(我希望是一个服务)。
Dependency Injection Documentation
现在您可以使用方法 isAlreadyApplicant
来模拟新服务了。
这是为了单元测试。
如果您需要功能测试,您可以创建一个 class,设置 id 并使用它而不是创建 new Team()
,这样您就可以控制您的 class,因为您没有进行测试实体 class 但函数
另一个解决方案是模拟库以将私有属性设置到您的测试中,但我不喜欢这个解决方案
您应该模拟这些对象,而不是在测试中使用 new User()
。然后你可以在这模拟任何方法,所以你不需要使用 $user->setId()
因为你将能够得到 $userMock->method('getId')->willReturn(10)
.
因此,与其实例化新对象并使用 setter 设置值,不如模拟这些对象并存根 getter。
参见 https://phpunit.de/manual/current/en/test-doubles.html 参考资料。
我正在尝试为我的应用程序创建单元测试,但我想得到一些建议。
我有这些方法:
/**
* This methods check if the user can apply to the team, it search if he have a username for the game and if he doesn't already applied for another team in the same tournament
* @param User $user
* @param Team $team
* @return bool|string
*/
public function canApply(User $user, Team $team) {
if ($user->getGamingUsername($team->getTournament()->getGame()) === null) {
return "Vous devez avoir un nom d'utilisateur pour pouvoir vous inscrire, renseignez le dans \"Mon profil\"";
} else if (false !== $teamAlreadyIn = $this->isAlreadyApplicant($user, $team)) {
return "Vous avez déjà postulé pour une équipe pour ce tournoi :
<a href=\"".$this->router->generate("mgd_team_show", array("id" => $teamAlreadyIn->getId()))."\">".htmlspecialchars($teamAlreadyIn->getName())."</a>";
}
return true;
}
/**
* This method search if the user is already in a team for the same tournament than the one passed in argument
* @param User $user
* @param Team $team
* @return bool|Team|mixed
*/
public function isAlreadyApplicant($user, Team $team) {
if (!$user || !$this->authorizationChecker->isGranted("ROLE_USER")) {
return false;
}
foreach ($user->getApplications() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getTeams() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
foreach ($user->getManagedTeam() as $userTeam) {
/** @var Team $userTeam */
if ($userTeam->getTournament()->getId() === $team->getTournament()->getId()) {
return $userTeam;
}
}
return false;
}
如您所见,第一个 (canApply) 调用第二个 (isAlreadyApplicant)。
但是当我尝试测试 canApply 时,我遇到了一些麻烦:这个方法调用 isAlreadyApplicant 并且在这个方法中我根据锦标赛的 id 进行比较。
在我的测试中 class,我不能“->setId()”,因为它是一个私有方法。那么我该如何处理呢? 从我的数据库中获取元素是否更好?
目前,我的测试方法之一如下所示:
/**
* The user is connected and try to apply to a team and applied for another team for another game
*/
public function testCanApplySecondTeamAnotherGame() {
$user = new User();
$game = new Game();
$anotherGame = new Game();
$team = new Team();
$anotherTeam = new Team();
$tournament = new TournamentTeam();
$anotherTournament = new TournamentTeam();
$team->setTournament($tournament);
$anotherTeam->setTournament($anotherTournament);
$tournament->setGame($game);
$anotherTournament->setGame($anotherGame);
$game->setName("TestGame");
$anotherGame->setName("AnotherGame");
$gamingProfile = new GamingProfile();
$gamingProfile->setGame($game);
$gamingProfile->setUsername("TestGameUsername");
$anotherGamingProfile = new GamingProfile();
$anotherGamingProfile->setGame($anotherGame);
$anotherGamingProfile->setUsername("TestAnotherGameUsername");
$user->setGamingProfiles(new ArrayCollection(array($gamingProfile, $anotherGamingProfile)));
$user->addApplication($anotherTeam);
$user->addTeam($anotherTeam);
$router = $this->createMock(Router::class);
$authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
$authorizationChecker->method("isGranted")->willReturn(true);
$applicationChecker = new ApplicationChecker($router, $authorizationChecker);
//Here, we try to apply to a team
$this->assertTrue($applicationChecker->canApply($user, $team));
}
如果您有任何问题,请不要犹豫! 祝你有个美好的一天!
这段代码比较耦合,很难用简单的方法进行测试。
我建议你采用方法 isAlreadyApplicant
并以服务为例。
在依赖注入之后,将新服务注入到您的实际服务中(我希望是一个服务)。
Dependency Injection Documentation
现在您可以使用方法 isAlreadyApplicant
来模拟新服务了。
这是为了单元测试。
如果您需要功能测试,您可以创建一个 class,设置 id 并使用它而不是创建 new Team()
,这样您就可以控制您的 class,因为您没有进行测试实体 class 但函数
另一个解决方案是模拟库以将私有属性设置到您的测试中,但我不喜欢这个解决方案
您应该模拟这些对象,而不是在测试中使用 new User()
。然后你可以在这模拟任何方法,所以你不需要使用 $user->setId()
因为你将能够得到 $userMock->method('getId')->willReturn(10)
.
因此,与其实例化新对象并使用 setter 设置值,不如模拟这些对象并存根 getter。
参见 https://phpunit.de/manual/current/en/test-doubles.html 参考资料。