【问题标题】:Mocking A Service in angular Karma Jasmine Testing在角业力茉莉花测试中模拟服务
【发布时间】:2020-03-27 04:24:34
【问题描述】:

我试图通过将服务添加到规范中的 providers 数组并添加带有它的函数的 createSpyObj 来模拟服务,但我收到以下错误:

从源“http:localhost:9876”访问“ng://DynamicTestModule/mycomponent_Host.ngfactory.js”处的 XMLHttpRequest

我做错了什么?

// .... 导入服务

mockService = jasmine.createSpyObj(['function1'])
testBed.configureTestingModule({
  providers:[{
      {provide: myService, useValue: mockService}
  }]
}).compileComponents()

【问题讨论】:

  • 您在导入myService 吗?你能分享整个错误信息吗?
  • 谢谢,但问题是别的,我自己解决了

标签: angular typescript unit-testing jasmine karma-jasmine


【解决方案1】:

您创建spy 的方式本身是错误的。从错误来看,似乎与无效导入或其他原因更相关。

正确的做法是:

describe("UserDetailComponent", () => {
  let component: UserDetailComponent;
  let fixture: ComponentFixture<UserDetailComponent>;
  const mockUserService = jasmine.createSpyObj("UserSvcService", ["getUserDetail"]);

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [UserDetailComponent],
      providers: [
        { provide: UserSvcService, useValue: mockUserService }
      ]
    }).compileComponents();
  }));
....
...
 it('should set some values using service',()=>{
   mockUserService.getUserDetail.and.returnValue(
      of({ data: 'somevalue'})
    );
   expect(someCondition).toBeDefined();
 })
)}

还有其他方法可以做到这一点,使用 Stubs 然后使用 useClass 在组件中插入。 you can refer to this article of mine to get the idea

【讨论】:

    【解决方案2】:

    假设您有一个名为 SharedService 的服务要测试

    // import the service from the desired location, i just indicated with @
    import { SharedService } from "@services"
    
    // create an instance inside describe
    let sharedService: SharedService
    
    // declare under providers in beforeEach
    providers: [SharedService]
    
    // create component and test fixture
    fixture = TestBed.createComponent(yourComponentName);
    component = fixture.componentInstance;
    sharedService = fixture.debugElement.injector.get(SharedService)
    
    // use compileComponents only if you are not using webpack or angular CLI 
    
    it('Should call MethodOne - sharedService ==> resolved', () => {
            let MockedData = {};
            spyOn(sharedService, 'someMethod').and.returnValue(Observable.of(MockedData));
            component.MethodOne();
            expect(sharedService.someMethod).toHaveBeenCalled();
        });
    

    【讨论】:

      【解决方案3】:

      我要做的是提供服务,但利用 Angular 的 HttpClientTestingModuleHttpTestingController 来配置您想要的每个单元测试的单独 http 响应。

      beforeEach(async(() => {
          TestBed.configureTestingModule({
              imports: [],
              providers: [SharedService]
          }).compileComponents();
      }));
      

      一旦您提供了服务,您就可以访问其中的所有内容。

      基本上,您可以创建模拟响应,并通过测试套件为您编写的每个单独测试“刷新”它们。这样可以为每个测试配置 HTTP 响应,而不是为您的整个服务测试套件提供一个响应。

      这是一个例子:

      it("should return valid response", fakeAsync(
         inject([HttpTestingController], (httpMock: HttpTestingController) => {
            let mockResponse = { success: true }
      
            httpMock.expectOne('endpoint name here').flush(mockResponse);
      
            fixture.whenStable().then(() => {
                //here's your acceptance criteria
            });
         });
      ));
      

      这里有一些关于它的文档:https://medium.com/netscape/testing-with-the-angular-httpclient-api-648203820712

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-12
        • 2023-04-06
        • 1970-01-01
        • 2014-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多