为什么PHPSpec正在采用模拟/存根方法?

时间:2015-06-29 07:36:37

标签: php phpspec

我从PHPSpec开始,我遇到了一些问题。 其中之一是我一直在

  

方法调用:              - 找(null)           在Double \ TaskRepositoryInterface \ TaskRepositoryInterface \ P95是不期望的,预期的调用是:              - findOneByGoogleId(exact(“googleId”))   我不知道为什么phpspec期待findOneByGoogleId。

这是我的规范示例:

public function it_should_synchronize_new_task_from_google_to_app(
    TaskDTO $taskDTO,
    TaskDTO $taskDTO2,
    TaskListDTO $taskListDTO,
    TaskRepositoryInterface $taskRepository,
    TaskListRepositoryInterface $taskListRepository,
    TaskList $taskList,
    AddTask $addTask
){
    $taskDTO->getGoogleId()->willReturn('googleId');
    $taskRepository->findOneByGoogleId('googleId')->willReturn(null);
    $taskDTO->getTitle()->willReturn('GoogleTitle');
    $taskListDTO->getId()->willReturn(1);
    $taskListRepository->find(1)->willReturn($taskList);
  //$addTask->toTaskList(Prophecy\Argument::type(TaskDTO::class),Prophecy\Argument::type(TaskListDTO::class))->shouldBeCalled();
  //$addTask->toTaskList(Prophecy\Argument::type(TaskDTO::class),Prophecy\Argument::type(TaskListDTO::class))->shouldBeCalled()->willReturn($taskDTO2);
    $addTask->toTaskList(Prophecy\Argument::type(TaskDTO::class),Prophecy\Argument::type(TaskListDTO::class))->willReturn($taskDTO2);
    $this->fromGoogleToApp($taskDTO, $taskListDTO)->shouldReturnAnInstanceOf('Itmore\Core\Entity\TaskDTO');
}

这是SUS:

public function fromGoogleToApp(TaskDTO $taskDTO, TaskListDTO $taskListDTO)
{
    if(!$taskDTO->getGoogleId()){
        throw new \ErrorException('not a google task');
    }
    $task = $this->taskRepository->findOneByGoogleId($taskDTO->getGoogleId());
    if(!$task){
        $task = new Task();
        $task->setTitle($taskDTO->getTitle());
        $taskList = $this->taskListRepository->find($taskListDTO->getId());
        $task->setTaskList($taskList);
        $addTask = new AddTask($this->taskRepository, $this->taskListRepository,$this->userRepository);

        try {
            $addTask->toTaskList(new TaskDTO($task), $taskListDTO);
        } catch (\ErrorException $e) {}

        return new TaskDTO($task);

    }else {
        if ($task->getTitle() != $taskDTO->getTitle()) {
            $task->setTitle($taskDTO->getTitle());
        }
        $this->taskRepository->update();
    }

    return new TaskDTO($task);
}

这就是PHPSpec正在踩踏的方法:

public function toTaskList(TaskDTO $taskDTO, TaskListDTO $taskListDTO)
{
    $taskList = $this->taskListRepository->find($taskListDTO->getId());
    if (!$taskList) {
        throw new \ErrorException('taskList not found');
    }

    $task = $this->taskRepository->find($taskDTO->getId());
    if ($task) {
        throw new \ErrorException('task already exists');
    }

    $task = new Task();
    $task->setTitle($taskDTO->getTitle());
    $task->setGoogleId($taskDTO->getGoogleId());
    $task->setTaskList($taskList);

    $this->taskRepository->add($task);

    return new TaskDTO($task);
}

正如你所看到的,我尝试了不同的方法来存根/模拟这个toTaskList方法,但它似乎不起作用。当我注释掉toTaskList测试传递时。我真的不明白为什么会这样。

1 个答案:

答案 0 :(得分:0)

您正在调用$ taskListDTO-> getId()两次,但只会将其删除一次。

我会将你的SUS重构成这样的东西:

public function fromGoogleToApp(TaskDTO $taskDTO, TaskListDTO $taskListDTO)
{
    if(!$taskDTO->getGoogleId()){
        throw new \ErrorException('not a google task');
    }
    $task = $this->taskRepository->findOneByGoogleId($taskDTO->getGoogleId());

    if(!$task){
        $taskList = $this->taskListRepository->find($taskListDTO->getId());

        $task = $this->taskManager->createNew()
            ->setTitle($taskDTO->getTitle())
            ->setTaskList($taskList);

        $addTask = $this->addTaskManager->createNew($this->taskRepository, $this->taskListRepository,$this->userRepository);

        $newTaskDTO = $this->taskDTOManager->createNew($task);

        try {
            $addTask->toTaskList($newTaskDTO, $taskListDTO);
        } catch (\ErrorException $e) {}

        return $newTaskDTO;

    }else {
        if ($task->getTitle() != $taskDTO->getTitle()) {
            $task->setTitle($taskDTO->getTitle());
        }
        $this->taskRepository->update();
    }

    return $this->taskDTOManager->createNew($task);;
}

这可以使用DI,你可以存根/模拟调用。

虽然你指明它你可能会注意到你需要模拟和存储很多东西,这通常暗示该方法做了太多事情,并且可能是一个好主意将一些任务委托给其他类。