1

I am trying to write a simple unit test for a client that was generated with nswag and it look

it('it create a call create on the api if new household', async(() => {
   const newHousehold = new Household();
   newHousehold.name = 'Test Household';
   store.dispatch(new SaveHousehold(newHousehold));

   const req = httpTestingController.expectOne('http://localhost:57461/api/Households');

   req.flush(newHousehold);

   expect(req.request.method).toEqual('POST');
}));

But I get the following error:

Failed: Automatic conversion to Blob is not supported for response type

I have tried several things to convert the newHousehold to a blob but it always returns blank or throws other errors. So how can I can I test this client?

FYI, I am also using NGXS for a store, so that is why it is calling the store.dispatch which fires the http request.

Here is the code for the action

@Action(SaveHousehold)
 public saveHousehold(
   { dispatch }: StateContext<HouseholdStateModel>,
   payload: SaveHousehold
 ) {
let subscription: Observable<Household>;

if (payload.household.id) {
  subscription = this.service.update(
    payload.household.id,
    payload.household
  );
} else {
  subscription = this.service.create(payload.household);
}

subscription.subscribe(result => {
  if (!payload.household.id) {
    dispatch(new LinkToExistingHousehold(result.id));
  }
},error=>{
  console.error(error);
});
 }

And here is the code for the service.create

create(entity: Household): Observable<Household | null> {
    let url_ = this.baseUrl + "/api/Households";
    url_ = url_.replace(/[?&]$/, "");

    const content_ = JSON.stringify(entity);

    let options_ : any = {
        body: content_,
        observe: "response",
        responseType: "blob",
        headers: new HttpHeaders({
            "Content-Type": "application/json", 
            "Accept": "application/json"
        })
    };

    return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => {
        return this.processCreate(response_);
    })).pipe(_observableCatch((response_: any) => {
        if (response_ instanceof HttpResponseBase) {
            try {
                return this.processCreate(<any>response_);
            } catch (e) {
                return <Observable<Household | null>><any>_observableThrow(e);
            }
        } else
            return <Observable<Household | null>><any>_observableThrow(response_);
    }));
}

The issue seems to be because the responseType specified in the create.

Jonathan
  • 1,725
  • 3
  • 19
  • 45
  • The dispatch method returns an observable meaning it isn't 'done' when it returns. You need to subscribe to it and complete your test in the function you pass to subscribe. Look at https://ngxs.gitbook.io/ngxs/concepts/store for an example where they reset a form once a dispatch has completed. – Rich Duncan Apr 20 '19 at 15:56
  • Yep I understand that part, I haven't got that far, my issue is in the http call that is dispatched. It is getting hit but throwing the error above. – Jonathan Apr 20 '19 at 16:22
  • Might be a good idea to post your action method then – Rich Duncan Apr 20 '19 at 18:29
  • @RichDuncan I have updated the example with more details – Jonathan Apr 20 '19 at 18:44
  • So I'm using the HttpClient class for this sort of interaction as documented here: https://angular.io/guide/http. Notice int he stack blitz example: https://stackblitz.com/angular/kekaxpkkdjm?file=src%2Fapp%2Fheroes%2Fheroes.service.ts that you can void having marshal your post data into JSON and the response processing can be done automatically as well. Also, why response type 'blob'? I would expect the service to return json no? – Rich Duncan Apr 20 '19 at 19:02
  • Yeah I am using a tool that auto generated this service called nswag and that is not how I would normally do it either, was more looking for a solution on how to solve it for the nswag implementation of the service. I feel like the blob is really complex for a json api. – Jonathan Apr 20 '19 at 19:03
  • Weird - it looks like Blob is supported maybe try ...request(....) – Rich Duncan Apr 20 '19 at 19:12
  • Can you be more specific where you would put that and what it would look like? – Jonathan Apr 20 '19 at 19:38
  • return this.http.request("post",...)... – Rich Duncan Apr 22 '19 at 19:42

1 Answers1

0

The solution is to flush your response as a Blob as follows:

req.flush(new Blob([JSON.stringify(newHousehold)], { type: 'application/json' }));
Matt
  • 1,446
  • 19
  • 17