使用flush()方法时:“响应类型不支持自动转换为JSON。”

时间:2019-05-23 13:07:40

标签: angular unit-testing

当我使用flush()方法测试HTTP请求时,出现此错误:响应类型不支持自动转换为JSON。您能否也向我解释一下flush()方法的目标。我不太了解

Thanks ! 

问题尚未真正解决。我们必须将async()方法添加到“ it”函数中,如下所示:“ it('should get the post',async(()=> {

import { TestBed } from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing"
import { DataService } from './data.service';
import { Observable } from 'rxjs';
import { Post } from './post.model';
import { HttpClientModule } from '@angular/common/http';

describe('DataService', () => {

  let service: DataService
  let  httpTestingController: HttpTestingController
  let attemptedPost : Post;
  const post = {
    userId: 1,
    id: 1,
    title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  };


  beforeEach(() => { TestBed.configureTestingModule({

    imports : [HttpClientTestingModule,HttpClientModule],
    providers : [DataService]
  });

    service = TestBed.get(DataService);
    httpTestingController = TestBed.get(HttpTestingController)
});

  it('should be created', () => {
    expect(service).toBeTruthy();
  });

  it('should get the post', () => {


    service.getPosts().subscribe( (postRetrieved) => {

      attemptedPost=postRetrieved;
    }); 

   const req =  httpTestingController.expectOne('https://jsonplaceholder.typicode.com/posts/1');
   req.flush(attemptedPost);
   // expect(attemptedPost).toEqual(post);

  });
});

3 个答案:

答案 0 :(得分:1)

您的错误是subscribe方法是async,所以您尝试这样做:

service.getPosts().subscribe( (postRetrieved) => {

      attemptedPost=postRetrieved;

   const req =  httpTestingController.expectOne('https://jsonplaceholder.typicode.com/posts/1');
   req.flush(attemptedPost);
   // expect(attemptedPost).toEqual(post);

});

答案 1 :(得分:0)

flush()方法是您的模拟请求将返回的方法。将其视为来自端点的值。在您的情况下,如果刷新attemptedPost是端点将返回的内容,那么您需要确保trydPost的模型和来自端点的真实模型是相同的,以便您的代码可以正常工作。

在代码中,您正在刷新attemptedPost,但从未为其分配值,您可以为其分配值或刷新post

此外,由于可观察对象是异步的,因此您需要在订阅中移动期望值。

答案 2 :(得分:0)

我无法让此代码在联机运行时环境中运行,但请尝试使其运行,希望它可以为您提供有关执行顺序的内幕,而imo可以帮助您理解代码。

import dask
from dask.distributed import Client
from dask_kubernetes import KubeCluster, KubeConfig, make_pod_spec

dask.config.set({"kubernetes.scheduler-service-type": "LoadBalancer"})
dask.config.set({"distributed.comm.timeouts.connect": 180})
image = "daskdev/dask"
cluster = "aks-cluster-prod3"
virtual_config = {
    "nodeSelector": {
        "kubernetes.io/role": "agent",
        "beta.kubernetes.io/os": "linux",
        "type": "virtual-kubelet",
    },
    "tolerations": [
        {"key": "virtual-kubelet.io/provider", "operator": "Exists"},
        {"key": "azure.com/aci", "effect": "NoSchedule"},
    ],
    "dnsConfig": {
        "options": [{"name": "ndots", "value": "5"}],
        "searches": [
            "default.svc.cluster.local",
            "svc.cluster.local",
            "cluster.local",
        ],
    },
}

# copied from: https://github.com/dask/dask-docker/blob/master/base/Dockerfile#L25
command_entrypoint_explicit = {
    "command": ["tini", "-g", "--", "/usr/bin/prepare.sh"],
}

pod_spec = make_pod_spec(
    image=image,
    extra_pod_config=virtual_config,
    extra_container_config=command_entrypoint_explicit,
    memory_limit="2G",
    memory_request="2G",
    cpu_limit=1,
    cpu_request=1,
    threads_per_worker=1,  # same as cpu
)

# az aks get-credentials --name aks-cluster1 --resource-group resource_group1
# cp ~/.kube/config ./aksconfig.yaml
auth = KubeConfig(config_file="./aksconfig.yaml", context=cluster,)
cluster = KubeCluster(
    pod_spec,
    auth=auth,
    deploy_mode="remote",
    scheduler_service_wait_timeout=180,
    n_workers=1,
)
client = Client(cluster)

第二个测试向您显示,在接受答案的情况下,永远不会执行匿名函数中的代码。

it("flush should work when it is called outside of the next-function that is given to subscribe", () => {

    let cc: number = -1;

    service.getPosts().subscribe((postRetrieved: ResponseTypeOfGetPosts): void => { // ResponseTypeOfGetPosts as in getPosts(): Observable<ResponseTypeOfGetPosts>

        expect(cc).toEqual(1); // ! not "-1"! - this code is executed by the call of flush(..)

        console.log("I was here -- 2nd --------------------------------------------------------------");

        cc = 2;

        expect(postRetrieved).toEqual(X_Y_Z);
      
    });
    
    const req = httpTestingController.expectOne('your-url-string');

    expect(cc).toEqual(-1);

    console.log("I was here -- 1st --------------------------------------------------------------");

    cc = 1;

    req.flush(X_Y_Z);   // insert a value of the type THIS_TYPE, that you used in your service in httpClient.get<THIS_TYPE>(...)
                        // but fill it, else the value is >undefined< what leads to your error

    expect(cc).toEqual(2);

    console.log("I was here -- 3rd --------------------------------------------------------------");

    cc = 3;
});

我希望这可以有所帮助。