当前位置: 首页 > 知识库问答 >
问题:

角度(8)-带有专用变量的单元测试服务[重复]

鲍高扬
2023-03-14

我想知道我正在构建和测试的服务的方法是否正确。我总是将我的类设计为尽可能的封装。所以,在构建角度服务时,我也用同样的方式构建它们。

下面是我的服务的一个片段:

private postUrl = 'https://localhost:44359/api/posts';
private currentGetPostsUrl = `${this.postUrl}?page=${this.pageNumber}&pageSize=${this.pageSize}`;

private filteredPostListSource = new Subject<IPostViewDto[]>();
filteredPostList$ = this.filteredPostListSource.asObservable();

// post list returned from the api
private originalPostList: IPostViewDto[];
// filtered list that is displayed to user
private filteredPostList: IPostViewDto[];

//get a list of posts that are paginated
getPosts(): Observable < IPostViewDto[] > {
  const urlToFetch = `${this.postUrl}?page=${this.pageNumber}&pageSize=${this.pageSize}`;

  // if the post list exists, return that post list
  if(this.originalPostList) {
  return of(this.originalPostList);
}

return this.http.get<IPostViewDto[]>(urlToFetch, { observe: 'response' })
  .pipe(
    map((response: HttpResponse<IPostViewDto[]>) => {
      const paginationHeader = JSON.parse(response.headers.get('X-Pagination'));
      this.totalCount = paginationHeader.totalCount;
      this.originalPostList = response.body;
      this.filteredPostList = [...this.originalPostList];
      return response.body;
    }),
    catchError(err => this.errorHandler(err))
  );
}

如上所述,我不允许组件直接访问私有变量,而是使用方法来完成所有交互。这里的问题是单元测试有点混乱。如果我想正确测试我的getPosts()方法是否正确返回我的原始PostList中的帖子列表,如果它存在,我必须在为超文本传输协议创建存根值后运行它一次,以确保私有字段设置,然后再次运行它,并比较我的存根值等于第二次运行getPosts()

这似乎不仅是一个糟糕的单元测试,还可能是服务本身没有正确构建以进行测试。

什么样的方式可以使其易于测试?我是否只需要创建getter/setter并测试它们?或者我上面描述的方法有效吗?

请注意,我这样设计它的原因是因为我不希望子组件/其他组件在没有显式方法调用的情况下意外更新这些属性(这样我就可以编写测试来确保情况如此)。这并不是因为只有一个组件访问这个服务。

共有2个答案

单勇
2023-03-14

我同意您不应该访问测试中的私有变量。如果你这样做了,当你需要做一些重构时,你的测试将是无用的。

我认为在测试中调用该方法两次没有问题。我假设这会发生在实际代码中,因为您正在实现缓存机制。“你的测试越像你的软件的使用方式,它们就越能给你信心。”

仇阳州
2023-03-14

您可以创建用于访问私有变量的getter方法,也可以将其更改为public并向其添加readonly。这样,其他组件/测试可以访问它,但无法更改它。

在我看来,你不应该两次调用方法来测试它们。根据你的例子,我可能会创建一个接受GET参数的函数。一旦有了这些,您就可以通过HttpClientTestingModule测试是否命中了正确的APIendpoint并获得了正确的数据对象。

 类似资料:
  • 我想对一个组件的功能进行单元测试。因此,我需要一个模拟服务(根据角度测试指南)。 这里是我的测试床: 那么,嘲笑服务价值的正确方法是什么呢? 弗兰克

  • 我已经构建了一种队列管理器,它与RxJs可观察对象一起工作,并逐个执行它们。现在我想测试这个,但是我想测试的所有方法都是私有的。 公共接口只有两个方法可以创建一个可观察对象并将其添加到队列管理器。 如果我尝试制作类似于PhpStorm的东西,分析表明它不可分配给type(并指公共方法)。 我不能把它提炼成公开的东西,因为这是一个复杂的逻辑,不应该被外界打断。

  • 我有一个简单的类,它包含一个列表: 关键是-我希望该列表只从DB加载一次。我想对这个功能进行单元测试。我是TDD的新手,我所能做的就是为某些列表编写一个公共getter和setter,并在单元测试中使用它们。但这在概念上是错误的--我不希望类的客户端直接使用这个成员变量。 在这种情况下,我如何正确地测试方法?

  • 本文向大家介绍AngularJS 单元测试服务,包括了AngularJS 单元测试服务的使用技巧和注意事项,需要的朋友参考一下 示例 服务编号 考试 跑!

  • 8 Node.js 单元测试 8.1 单元测试 对于一个程序员来说不仅要写代码,还要验证一下代码写得到底对不对,写单元测试就是一个通用且有效的解决方案。单元测试很重要,可以将错误扼杀在摇篮中,如果你认为没有写单元测试也过得很好,也许等我介绍完 mocha 之后,你会改变主意的。 下面给出一个栗子,领导给了小明一个计算器的项目,不过这个项目周期比较长,后期需要增加更多的人手,所以对于每一个模块都要有

  • 我已经开始考虑在我的项目中围绕一些业务逻辑添加一些单元测试。 我想测试的第一个方法是服务层中的一个方法,它返回给定节点的子节点列表。 该方法如下所示: 我想象这样的测试方法是提供一个假树结构,然后测试提供节点是否返回正确的子节点。 ssdsContext是一个对象上下文。 我已经看到可以为提取和接口如何模拟ObjectContext或ObjectQuery 我还读到,as Entity Frame