如何模拟一个对象并验证给定的参数是否提供给了这个模拟

How to mock an object and verify a given parameter was provided to this mock

我在 ng-mocks:

的帮助下尝试测试一个 HttpInterceptor
    @Injectable()
    export class AuthTokenInterceptor implements HttpInterceptor {
      constructor(private store: Store) {}
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const currentToken = this.store.selectSnapshot(state => state.accounts.accessToken);
    
        if (currentToken) {
          req = req.clone({
            setHeaders: { Authorization: `Bearer ${currentToken}` },
          });
        }
        return next.handle(req);
      }
    }

我无法了解如何提供 next 参数,特别是因为我想检查对象是否具有 setHeaders 属性 存在(或不存在):

    describe('Unauth guard test', () => {
      beforeEach(() => {
        return MockBuilder(AuthTokenInterceptor, AppModule).mock(Store);
      });
    
      it('should allow access if not authenticated', () => {
        //Arrange
        const fakeToken = 'fakeToken';
        const storeDispatchSpy = MockInstance(Store, 'selectSnapshot', jasmine.createSpy().and.returnValue(fakeToken));
        const httpHandlerSpy = MockInstance(HttpHandler, 'handle', jasmine.createSpy().and.returnValue(fakeToken));
        const fixture = MockRender(AuthTokenInterceptor);
        const interceptor = fixture.point.componentInstance;
       const request = new HttpRequest('GET', 'http://localhost:4200/');
    
        //Act
        const result = interceptor.intercept(request, httpHandlerSpy.???);//How to provide a mock of HttpHandler?
    
        //Assert
        expect(storeDispatchSpy).toHaveBeenCalled();
        expect(httpHandlerSpy).toHaveBeenCalledOnceWith(???);//How to verify that one parameter of the HttpRequest is set to specific value?
      });
    });

但是如何为拦截方法提供模拟实例?更复杂的是,如何检查我的间谍是否已使用具有特定值的对象调用?

在您的情况下,您需要提供 mockStore + 将您的拦截器与其他拦截器隔离。

来自 ng-mocks docs and http interceptors 的示例。

https://codesandbox.io/s/intelligent-stallman-9bwup0?file=/src/test.spec.ts

describe('AuthTokenInterceptor', () => {
  beforeEach(() => {
    return (
      MockBuilder(AuthTokenInterceptor, AppModule)
        // required for interceptors
        .exclude(NG_MOCKS_INTERCEPTORS)
        .keep(HTTP_INTERCEPTORS)

        .replace(HttpClientModule, HttpClientTestingModule)
    );
  });

  it('adds header', () => {
    // creating an empty fixture
    const fixture = MockRender('', null, false);

    // stubbing store
    const store = ngMocks.findInstance(Store);
    ngMocks.stubMember(store, 'selectSnapshot', callback =>
      callback({
        accounts: {
          accessToken: 'Testing',
        },
      }),
    );

    // render
    fixture.detectChanges();

    // instances to test how HttpClient uses interceptors
    const client = ngMocks.findInstance(HttpClient);
    const httpMock = ngMocks.findInstance(HttpTestingController);

    // Let's do a simple request.
    client.get('/target').subscribe();

    // Now we can assert that a header has been added to the request.
    const req = httpMock.expectOne('/target');
    req.flush('');
    httpMock.verify();

    // asserting headers
    expect(req.request.headers.get('Authorization')).toEqual(
      'Bearer Testing',
    );
  });
});