Angular-使用Jasmine监视HttpClient中的链接方法

时间:2018-10-26 14:20:44

标签: angular typescript jasmine angular-httpclient

我有一种情况需要监视在另一个方法被调用之后被调用的方法。

这是正在测试的课程/方法:

@Injectable()
export class SomeService {

  constructor(private customHttpClient: CustomHttpClient) {
  }

    updateSomethingCool(signerVO: SignerVO): Observable<SignerVO> {

    // ...

    return this.customHttpClient.withCustomOverrides(new CustomErrorHandlerHttpInterceptorOverride({ passthroughStatusCodes: [BAD_REQUEST, BAD_GATEWAY] }))
        .put<SignerVO>(`/my/url/goes/here`, signerVO);
    }
}

此类使用CustomHttpClient,如下所示:

    @Injectable()
    export class CustomHttpClient extends HttpClient {
        private interceptors: HttpInterceptor[] | null = null;

        constructor(private injector: Injector,
            originalHandler: HttpHandler, private originalBackend: HttpBackend) {
            super(originalHandler);
        }

        public withCustomOverrides(...overrides: CustomHttpInterceptorOverride[]): HttpClient {

            // do very customizable things here

            return new CustomDelegatingHttpClient(
                new CustomHttpInterceptingHandler(this.originalBackend, this.interceptors, overrides));
        }
    }

    export class CustomDelegatingHttpClient extends HttpClient {
        constructor(private delegate: HttpHandler) {
            super(delegate);
        }
}

这是我在单元测试中尝试确实调用过put方法的情况,因此,我需要监视put方法:

describe(SomeService.name, () => {
let service: SomeService;
let customHttpClient: CustomHttpClient;

let emptySignerVO: SignerVO = new SignerVO();

beforeEach(() => {
    customHttpClient= <CustomHttpClient>{};
    customHttpClient.put = () => null;
    customHttpClient.withCustomOverrides = () => null;

    service = new SomeService(customHttpClient);
});

describe('updateSomethingCool', () => {

    it('calls put', () => {
        spyOn(customHttpClient, 'put').and.stub();

        service.updateSomethingCool(emptySignerVO);

        expect(customHttpClient.put).toHaveBeenCalled();
    });
});

现在,当我运行此命令时,很明显我收到以下失败消息:

TypeError: Cannot read property 'put' of null

但是,我不完全知道如何在测试的put部分中定义withCustomOverridesbeforeEach方法。

请注意,CustomHttpClient只是围绕Angular HttpClient的定制包装类,它允许一些更详细的功能。

谢谢您的帮助!

3 个答案:

答案 0 :(得分:0)

我认为您应该注入httpClient;

beforeEach((http: HttpClient) => {
  httpClient = http;
  httpClient.put = () => null;
  httpClient.withCustomOverrides = () => null;
  service = new SomeService(log, httpClient);});

答案 1 :(得分:0)

您是否使用Angular依赖项注入将HttpClient注入到CustomHttpClient中?在测试依赖于HttpClient的服务时,您可以使用HttpTestingController,对于服务单元测试,它可能如下所示:

it(`should get a new data instance of type T`, 
  async(inject([TestDataService, HttpTestingController],
  (service: TestDataService, backend: HttpTestingController) => {
    // ... tests here
  })
));

答案 2 :(得分:0)

好吧,最后我实际上并没有那么遥远。实际的测试代码很好。 import mysql.connector from bs4 import BeautifulSoup import requests URL = "https://www.tripadvisor.com.au/Restaurants-g255068-c8-Brisbane_Brisbane_Region_Queensland.html" def get_info(link): mydb = mysql.connector.connect( host="localhost", user="root", passwd = "123", database="mydatabase" ) mycursor = mydb.cursor() mycursor.execute("DROP TABLE if exists webdata") mycursor.execute("CREATE TABLE if not exists webdata (name VARCHAR(255), bubble VARCHAR(255), review VARCHAR(255))") response = requests.get(link) soup = BeautifulSoup(response.text,"lxml") for items in soup.find_all(class_="shortSellDetails"): name = items.find(class_="property_title").get_text(strip=True) bubble = items.find(class_="ui_bubble_rating").get("alt") review = items.find(class_="reviewCount").get_text(strip=True) mycursor.execute("INSERT INTO webdata (name,bubble,review) VALUES (%s,%s,%s)",(name,bubble,review)) mydb.commit() #I wish to use the follwing three lines within another function to do the same mycursor.execute("SELECT * FROM webdata") for item in mycursor.fetchall(): print(item) if __name__ == '__main__': get_info(URL) 方法需要更新如下:

beforeEach()

我基本上只需要将beforeEach(() => { customHttpClient = <CustomHttpClient>{}; customHttpClient.put = () => null; customHttpClient.withCustomOverrides = () => customHttpClient; service = new SomeService(customHttpClient); }); 对象分配给customHttpClient方法。

如果您查看实际调用中方法链接的流程,那实际上是有道理的。