首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >方法被期望被调用1次,实际上被称为0次。在Symfony中进行测试

方法被期望被调用1次,实际上被称为0次。在Symfony中进行测试
EN

Stack Overflow用户
提问于 2022-07-08 18:21:22
回答 1查看 64关注 0票数 0

我需要一个小小的帮助来做一个简单的测试。我正在尝试测试blog post delete端点,在这里它会同时删除post及其注释。在postController方法中,它从另外两个存储库(postRepository和commentsRepository)调用另外两个方法来完全删除post。控制器中的方法如下所示:

代码语言:javascript
复制
public function deletePost(Request $request, $postId)
{
    $this->postRepository()->deletePost($postId);
    $this->commentsRepository()->deleteComments($postId);

    return $this->response(new JsonResponse('', 204));
}

我只需要检查deletePost方法和deleteComments是否被调用过一次。现在我明白了:

代码语言:javascript
复制
Expectation failed for method name is "deletePost" when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.

和deleteComments一样。现在我觉得这个模拟没有正常工作。下面是postRepository的deletePost方法和评注库的deleteComments方法:

代码语言:javascript
复制
// postRepository's
public function deletePost($postId)
{
    // ... some code 
}

// commentsRepository
public function deleteComments($postId)
{
    // ... some code 
}

下面是一个测试:

代码语言:javascript
复制
public function testDelete()
{
    $post = $this->postRepository()
      ->findOne(['id' => PostDataSeeder::POST_ID]);

    $route = $this->getUrl('api_delete_post', [
      '_format' => 'json',
      'postId' => $post->getId()
    ]);

    $this->client->request('DELETE', $route, [], [], [
      'CONTENT_TYPE' => 'application/json',
    ]);

    // check if deletePost method in postRepository is being called
    $postRepositoryMock = $this->createMock(PostRepository::class);
    $postRepositoryMock
      ->expects($this->once())
      ->method('deletePost')
      ->with($post->getId());

    // check if deleteComments method in commentsRepository is being called
    $commentsRepositoryMock = $this->createMock(CommentsRepository::class);
    $commentsRepositoryMock
      ->expects($this->once())
      ->method('deleteComments')
      ->with($post->getId());
}

这是我实际代码的最小表示。除了考试,一切都很完美。请帮我测试一下。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-08 19:40:24

当您通过$this->client->request...进行调用时,您将调用未更改的控制器,因此不会更改(而不是模拟)存储库。

在发出请求和在模拟类上“运行”it之前,您应该在容器中替换存储库。这可以通过Symfonys的env特定服务文件(即services_test.ymltest/services.yml )来实现。

我在这里看到的更大的问题是,您试图使用webTests运行模拟,这是两种方法的混合:网络测试和单元测试。

Web测试应该运行在未经修改的代码上(尽可能多地完成),但是运行在固定的环境上。在这种情况下,这将意味着一个包含预定义数据的单独的测试数据库(固定设备可以做到这一点)。在请求发出之后,您可以从容器中获取repo,并检查条目是否实际被删除。

单元测试更接近于您正在做的工作。首先创建postController所有依赖项的模拟,并在测试中实例化它。然后运行所有模拟参数(或只是实例化对象)的$postControllerInstance->deletePost(...),然后检查调用了哪个模拟函数。

总结不完全正确的句子: web测试应该检查是否一切都工作正常;单元测试应该检查是否一切都被正确调用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72915519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档