簡體   English   中英

Angular 2 RC 如何對 observable 進行單元測試

[英]Angular 2 RC how to unit test an observable

我正在為 angular 2 RC 應用程序編寫一些測試,並且在測試 observable 時遇到了一些問題。 我模擬了方法設置它的類型為 observable 但是當被測試的單元嘗試訂閱模擬的 observable 時,我收到錯誤'Cannot read property 'subscribe' of undefined'

我正在測試我的DashboardComponent ,它注入一個model3DService並調用model3DService.get3DModels() ,這是一個執行 http 請求並返回一個 3D 模型對象數組的可觀察對象。

這是一些示例代碼:

儀表板組件

import { Model3DService } from '../../services/model3D/model3D.service';
import { ProjectService } from '../../services/project/project.service';

@Component({
  selector: 'cmg-dashboard',
  styles: [require('./css/dashboard.scss')],
  template: require('./dashboard.html')
})
export class DashboardComponent implements OnInit {
  constructor(
    private projectService: ProjectService,
    private model3DService: Model3DService
  ) { }

  ngOnInit (): void {
    this.model3DService.get3DModels().subscribe((res: any[]) => {
      this.findProjects(res);
      this.models = res;
      this.projectService.isProjectSelected = true;
      this.createProject(res[0]);
    });
  }
}

模型3D服務

@Injectable()
export class Model3DService {
 private models: any[] = [];

 public get3DModels (): Observable<any> {
    return this.http.get('../../../json/3DModel.json')
    .map(( res: Response ) => {
      this.models = res.json();
      return this.models;
    });
  }
}

好的,現在我們有待測試的測試,就是我正在編寫的測試。

儀表板組件規格

class MockModel3DService {
  public get3DModels(): Observable<any> {
    return;
  }
}

describe('Dashboard Component', () => {
  beforeEachProviders(() => {
    return [
      DashboardComponent,
      provide(ProjectService, {
        useClass: MockProjectService
      }),
      provide(Model3DService, {
        useClass: MockModel3DService
      })
    ];
  });

  describe('ngOnInit', () => {
    it('should call model3DService.get3DModels on init', (inject([DashboardComponent], (dashboardComponent: DashboardComponent, model3DService: MockModel3DService) => {
      dashboardComponent.ngOnInit();
      expect(model3DService.get3DModels).toHaveBeenCalled();
    })));
  });
});

這個概念類似於測試 AngularJS $q承諾。 存根方法返回一個可觀察的模擬。 該方法可以返回一個繼承了Observable的主題,但也具有可觀察對象和觀察者的屬性。

可以為新的主題提供就地模擬值,需要事先定義模擬的承諾(主題與延遲共享此屬性,請參閱相關問題)。

RxJS 4 主題有hasObservers方法, hasObservers subscribe間諜。 RxJS 5 主題錯過了該方法,但它們公開了observers屬性。

很可能它應該是這樣的

let subject: Subject;

class MockModel3DService {
  public get3DModels(): Observable<any> {
    return subject;
  }
}

...
// beforeEach(...)
subject = new Subject;
...

// it(...)
const models = ['mocked'];
dashboardComponent.ngOnInit();

expect(subject.observers.length).toBe(1);

subject.next(models);
expect(model3DService.get3DModels).toHaveBeenCalled();
expect(dashboardComponent.models).toBe(models);
...

您的 MockModel3DServic.get3DModels 不返回可觀察對象。

import { of } from 'rxjs';

class MockModel3DService { 
  public get3DModels(): Observable<any> {
   return of(yourResponse)
 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM