【问题标题】:Error in angular unit test cases: TypeError: this.userService.currentUser.subscribe is not a function角度单元测试用例中的错误:TypeError: this.userService.currentUser.subscribe is not a function
【发布时间】:2019-11-25 19:41:35
【问题描述】:

我在运行 Angular 单元测试用例时遇到此错误:

测试结果

SidebarComponent
   × should create
    TypeError: this.userService.currentUser.subscribe is not a function

sidebar.component.spec.ts

describe('SidebarComponent', () => {
  let fixture: ComponentFixture<SidebarComponent>;
  let mockUserService;

  beforeEach(() => {
    mockUserService = jasmine.createSpyObj(['currentUser']);

    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      declarations: [SidebarComponent],
      schemas: [NO_ERRORS_SCHEMA],
      providers: [{ provide: UserService, useValue: mockUserService }]
    });

    fixture = TestBed.createComponent(SidebarComponent);
  });

  fit('should create', () => {
    mockUserService.currentUser.and.returnValue(of('Here goes an object'));
    fixture.detectChanges();
    expect(SidebarComponent).toBeTruthy();
  });
});

sidebar.component.ts

ngOnInit() {
    this.userService.currentUser.subscribe(currentUser => {
        // Some code here
    });
}

package.json

"devDependencies": {
    "@types/jasmine": "2.8.8",
    "@types/jasminewd2": "2.0.3",
    "@types/node": "9.6.23",
    "jasmine-core": "2.99.1",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "4.2.0",
    "karma-chrome-launcher": "2.2.0",
    "karma-cli": "2.0.0",
    "karma-coverage-istanbul-reporter": "1.4.3",
    "karma-jasmine": "2.0.1",
    "karma-jasmine-html-reporter": "1.4.0",
    "karma-junit-reporter": "1.2.0",
    "karma-spec-reporter": "0.0.32",
    "protractor": "6.0.0",
    "rxjs-tslint": "0.1.7",
}

user.service.ts

@Injectable({ providedIn: 'root'})
export class UserService {
  private currentUserSubject = new BehaviorSubject({});
  public currentUser: Observable<User> = this.currentUserSubject.asObservable().pipe(distinctUntilChanged());

  setUser(user) {
      this.currentUserSubject.next({ ...newUser });
  }
}

据我所知,要解决这个问题,我们需要在以下语句中使用:

mockUserService.currentUser.and.returnValue(of('Here going an object'));

其中 of 是从 'rxjs' 导入的。当我记录 of('Here going an object') 的值时,它表明它是可观察的。

我该如何解决这个问题?

【问题讨论】:

  • 你可以在这里张贴userService代码
  • 在问题中添加。

标签: angular jasmine karma-jasmine angular-test


【解决方案1】:

spyOn模拟具体的服务方法怎么样:

const userService = TestBed.get(UserService);
const mockedResponse = {}; // Modify as per your need
spyOn(userService, 'currentUser').and.callFake(() => {
  return of(mockedResponse);
});

这对我有用。

【讨论】:

    【解决方案2】:

    在对这个测试做了一些工作之后,我发现我们不能使用 spyOn(userService, 'currentUser')。原因很明显,currentUser 不是一个函数,而是一个变量,我们在其中分配了一个 observable。 SpyOn 将在此创建一个假函数,但我们需要的是一个 observable。所以我们可以使用 userService.setUser 方法来适当地设置 currentUser 的值。

    sidebar.component.spec.ts

    describe('SidebarComponent', () => {
      let component: SidebarComponent;
      let fixture: ComponentFixture<SidebarComponent>;
      let userService: UserService;
    
      beforeEach(done => {
        TestBed.configureTestingModule({
        imports: [HttpClientTestingModule, RouterTestingModule],
        declarations: [SidebarComponent],
        schemas: [NO_ERRORS_SCHEMA]
      })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(SidebarComponent);
        component = fixture.componentInstance;
    
        userService = TestBed.get(UserService);
        userService.setUser(userInfo);
    
        fixture.detectChanges();
        done();
      });
     });
    
     it('should create', done => {
       expect(component).toBeTruthy();
       done();
     });
    })
    

    【讨论】:

      【解决方案3】:

      你可以做类似的嘲笑:

      export const mockUserService= {
          currentUser = {
              subscribe() {
                return of({ 
                    // whatever here
                });
              }
          }
      };
      

      代码创建了一个虚假服务。这个假服务可以添加被测试的组件使用的所有功能和成员。

      【讨论】:

      • 为什么我们不能使用下面的方式? mockUserService = jasmine.createSpyObj(['currentUser']);我知道我可以编写完整的模拟服务,但它不会为我增加不必要的代码,因为要模拟的服务太多了。
      • 不确定...也许这也可行:jasmine.createSpyObj([{currentUser = {subscribe() {...}}]);
      猜你喜欢
      • 2022-09-29
      • 2019-06-06
      • 2019-03-22
      • 2018-07-30
      • 1970-01-01
      • 2021-04-19
      • 2019-02-08
      • 1970-01-01
      • 2015-11-01
      相关资源
      最近更新 更多