Architecture PhpSpec正确测试服务层
应用程序有多个服务,其中一些功能与多个服务重叠。由于我一次只能测试一项服务 背景: 群组服务可以创建诸如“红色汽车”、“蓝色汽车”之类的群组。 汽车服务可以将汽车分配给各个组 团体服务:Architecture PhpSpec正确测试服务层,architecture,tdd,repository-pattern,behat,phpspec,Architecture,Tdd,Repository Pattern,Behat,Phpspec,应用程序有多个服务,其中一些功能与多个服务重叠。由于我一次只能测试一项服务 背景: 群组服务可以创建诸如“红色汽车”、“蓝色汽车”之类的群组。 汽车服务可以将汽车分配给各个组 团体服务: function createGroup($name); function assignCarToGroup($car, $group); 汽车服务: function createGroup($name); function assignCarToGroup($car, $group); 问题: 当我
function createGroup($name);
function assignCarToGroup($car, $group);
汽车服务:
function createGroup($name);
function assignCarToGroup($car, $group);
问题:
当我在PhpSpec中描述汽车服务时,我想确保它能够检查汽车是否已成功分配给一个组
要做到这一点,在将汽车分配给该小组之前,该小组必须存在
问题:
我需要在运行文件之前创建组。这就是我面临的问题
如果我依靠前面的示例(GroupServiceSpec)来创建组,我会使测试变得非常脆弱
如何测试车辆是否已在车辆服务范围内成功分配
GroupService.php
<?php
namespace App;
class GroupService
{
private $group_repository;
public function __construct($group_repository)
{
$this->group_repository = $group_repository;
}
public function CreateGroupServiceCall($name)
{
return $this->group_repository->createGroup($name);
}
}
<?php
namespace App;
class CarService
{
private $car_repository;
public function __construct($car_repository)
{
$this->car_repository = $car_repository;
}
public function AssignCarToGroupServiceCall($car, $group_name)
{
return $this->car_repository->assignCarToGroup($car, $group_name);
}
}
您的汽车服务规格应该如下所示:
class CarServiceSpec extends ObjectBehavior
{
function let(CarRepository $carRepository)
{
$this->beConstructedWith($carRepository);
}
function it_is_initializable()
{
$this->shouldHaveType(CarService::class);
}
function it_can_assign_car_to_group(CarRepository $carRepository)
{
$car = 'Car I';
$group_name = 'Group1';
$carRepository->assignCarToGroup($car, $group_name)->shouldBeCalled()->willReturn(true);
$this->AssignCarToGroupServiceCall($car, $group_name)->shouldReturn(true);
}
}
我认为您可能对您的用例使用了错误的工具。Phpspec是用于单元测试的,所以如果您指定了汽车服务,那么您可能必须使用存根组服务。如果您想测试两者之间的集成,请使用Behat.Hello@gvf,非常感谢。实际上,我也在使用Behat。但是,我还想确保这个特定的函数在单元测试级别上工作。我认为嘲笑它是不够的,因为需要真正的条目。你会让它不进行单元测试吗?或者如果你想在单元测试级别对它进行测试,你的解决方案是什么?单元测试单独测试一个类,你想测试两个类之间的交互,所以我要做的是将测试移到Behat。如果您发布这两个类的完整代码,我可能会为您提供进一步的帮助。@gvf下面是我编写的代码的快速实现:我还将它添加到问题中。好的,首先,不要调用类“*Service.php`:-”),它太模糊,如果您有多个服务,会发生什么?在你的情况下,在CarServiceSpec,你只能说明行为:你只能说明调用<代码> CARYRealPosioS>分配CudioGue,没有别的。谢谢你GVF在这部分之后,我应该认为它是“验证”的,即使我知道结果不在那里吗?我可以说,“我的重点是部件,是否调用了正确的方法?”非常感谢,这就是您可以做的。如果您想确保它在DB中持久化,那么请进行Behat测试。非常感谢!整个事情也有behat在上面,我只是想确定一下。非常感谢。
<?php
namespace spec\App;
use App\GroupRepository;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class GroupRepositorySpec extends ObjectBehavior
{
function letGo()
{
# Clean up and remove all DB files
array_map('unlink', glob(__DIR__ . "/../../*.db"));
}
function it_is_initializable()
{
$this->shouldHaveType(GroupRepository::class);
}
function it_can_create_group()
{
$status = $this->createGroup('test');
$status->shouldBe(true);
}
}
<?php
namespace spec\App;
use App\CarRepository;
use App\CarService;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarServiceSpec extends ObjectBehavior
{
function let()
{
$car_repository = new CarRepository();
$this->beConstructedWith($car_repository);
}
function it_is_initializable()
{
$this->shouldHaveType(CarService::class);
}
function it_can_assign_car_to_group()
{
$car = 'Car I';
$group_name = 'Group1';
$this->AssignCarToGroupServiceCall($car, $group_name)->shouldBe(true);
}
}
<?php
namespace spec\App;
use app\CarRepository;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarRepositorySpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(CarRepository::class);
}
function it_can_assign_car_to_group()
{
# how can I test this part, as the group is not existing now.
# If I'm not to create the group, how can I test if this code works at all?
# Do I have a design error?
$car = 'Car1';
$group_name = 'Company';
$this->assignCarToGroup($car, $group_name)->shouldBe(true);
}
}
class CarServiceSpec extends ObjectBehavior
{
function let(CarRepository $carRepository)
{
$this->beConstructedWith($carRepository);
}
function it_is_initializable()
{
$this->shouldHaveType(CarService::class);
}
function it_can_assign_car_to_group(CarRepository $carRepository)
{
$car = 'Car I';
$group_name = 'Group1';
$carRepository->assignCarToGroup($car, $group_name)->shouldBeCalled()->willReturn(true);
$this->AssignCarToGroupServiceCall($car, $group_name)->shouldReturn(true);
}
}