การทดสอบเชิงมุมล้มเหลวด้วยล้มเหลวในการเรียกใช้ 'ส่ง' ใน 'XMLHttpRequest'


146

ฉันกำลังพยายามทดสอบองค์ประกอบเชิงมุม 4.1.0 ของฉัน -

export class CellComponent implements OnInit {
  lines: Observable<Array<ILine>>;
  @Input() dep: string;
  @Input() embedded: boolean;
  @Input() dashboard: boolean;
  constructor(
    public dataService: CellService,
    private route: ActivatedRoute,
    private router: Router, private store: Store<AppStore>) {
  }
}

อย่างไรก็ตามการทดสอบ "ควรสร้าง" แบบง่ายจะทำให้เกิดข้อผิดพลาดที่เป็นความลับนี้ ...

NetworkError: ล้มเหลวในการดำเนินการ 'ส่ง' ใน 'XMLHttpRequest': ล้มเหลวในการโหลด 'ng: ///DynamicTestModule/module.ngfactory.js'

ดังนั้นฉันพบคำถามนี้ซึ่งแสดงให้เห็นว่าปัญหาคือองค์ประกอบมี@Input)_params ที่ไม่ได้ตั้งค่า แต่ถ้าฉันแก้ไขการทดสอบของฉันเช่นนั้น:

  it('should create', inject([CellComponent], (cmp: CellComponent) => {
    cmp.dep = '';
    cmp.embedded = false;
    cmp.dashboard = false;
    expect(cmp).toBeTruthy();
  }));

ดังนั้นฉันยังคงได้รับปัญหาเดียวกันในทำนองเดียวกันหากฉันลบ@Input()คำอธิบายประกอบออกจากองค์ประกอบก็ยังคงไม่แตกต่างกัน ฉันจะทำให้การทดสอบเหล่านี้ผ่านได้อย่างไร


1
ในการสร้างองค์ประกอบคุณต้องให้การอ้างอิงทั้งหมด คุณสามารถแสดงการตั้งค่าการทดสอบทั้งหมดได้หรือไม่? ฉันจะพยายามทำให้เกิดปัญหาบนplnkr
Aleksandr Petrovskij

1
ฉันมีปัญหาเดียวกันนี้และพบโพสต์เดียวกับที่คุณทำ ฉันสามารถค้นหาวิธีแก้ปัญหา ฉันสิ้นสุดการโพสต์คำถามอื่น แต่คุณสามารถดูได้ที่นี่: stackoverflow.com/a/45419372/6739517 หวังว่ามันจะช่วยได้!
Niles Tanner

ดูสิ่งนี้: github.com/angular/angular-cli/issues/7296
titusfx

คำตอบ:


343

นี่เป็นปัญหาของ Angular Cli ใหม่ ทำการทดสอบด้วย--sourcemaps=falseและคุณจะได้รับข้อความแสดงข้อผิดพลาดที่ถูกต้อง

ดูรายละเอียดได้ที่นี่: https://github.com/angular/angular-cli/issues/7296

แก้ไข:

ชวเลขสำหรับเรื่องนี้คือ:

ng test -sm=false

ในมุมของ 6 คำสั่งคือ:

ng test --source-map=false


20
คุณฮีโร่ที่แน่นอน ฉันต่อสู้กับกำแพงด้วยความหงุดหงิดกับการขาดข้อมูลจากข้อความแสดงข้อผิดพลาดการทดสอบหน่วยเชิงมุมจนกระทั่งฉันพบสิ่งนี้ จำเป็นมาก
Alan Smith

1
คำตอบนี้ช่วยชีวิตฉันไว้ได้จริงๆ! ฉันใกล้จะยอมแพ้กับการพัฒนาโดยทั่วไปหลังจากใช้เวลาทั้งวันทั้งคืนเพื่อพยายามแก้ไขปัญหานี้ดังนั้นฉันจึงสามารถหยุดการเป็นบุคคลที่ล้มเหลวในการสร้าง
user1806692

วันนี้ฉันเจอข้อผิดพลาดนี้: HeadlessChrome 65.0.3325 (Mac OS X 10.13.4) ข้อผิดพลาด {"ข้อความ": "ข้อผิดพลาดของสคริปต์ \ nat: 0: 0", "str": "ข้อผิดพลาดของสคริปต์ \ nat: 0 : 0 "} และการลบ --sourcemap = false จะแสดงข้อมูลเพิ่มเติม
penghui

11
ng test --source-map = false ... ทำงานใน Angular CLI 6
danday74

@ danday74 FTW! หลังจากเขียนไฟล์ทดสอบที่ซับซ้อนแล้วการติดใจกับสิ่งนี้นั้นโหดร้าย
แบรดริชาร์ดสัน

21

ฉันมีปัญหาเดียวกันโดยใช้ angualar cli 6 ฉันใช้แท็กนี้เพื่อรับข้อความแสดงข้อผิดพลาดที่ถูกต้อง:

ng test --source-map=false

อาจจะช่วยใครซักคน :)


8

สำหรับกรณีของฉันมีปัญหาข้อมูลจำลองและในกรณีที่Arrayฉันกลับมาstringจากจำลอง

someApi = fixture.debugElement.injector.get(SomeApi);
spyOn(someApi, 'someMethod')
  .and.returnValue(Observable.of('this is not a string but array'));

ข้อความแสดงข้อผิดพลาดเบี่ยงเบนความสนใจจริง ๆ และไม่ได้บอกข้อผิดพลาดจริง การรันng test --source=falseชี้ข้อผิดพลาดและบรรทัดที่ถูกต้องและช่วยให้ฉันแก้ไขได้อย่างรวดเร็ว

หลายครั้งที่มันเกิดขึ้นเมื่อคุณจำลองข้อมูลไม่สมบูรณ์หรือไม่ถูกต้อง


8

คุณสามารถตั้งค่าคุณสมบัติอินพุต ()เป็นค่าเริ่มต้นในcomponent.ts

@Input() tableColumns: Array<any> = [];  
@Input() pageObj: any = '';

หรือ

แก้ไขไฟล์component.spec.tsของคุณด้วยวิธีต่อไปนี้

beforeEach(() => {  
   fixture = TestBed.createComponent(MyComponent);  
   component = fixture.componentInstance;  
   component.tableColumns = [];  
   component.pageObj = '';  
   fixture.detectChanges();  
});

4

เป็นข้อเสนอแนะดังกล่าวข้างต้นที่นี่: https://stackoverflow.com/a/45570571/7085047ngOnInitปัญหาของฉันอยู่ในของฉัน ฉันกำลังเรียกใช้พร็อกซีคอนโทรลเลอร์ REST ที่สร้างโดยการล้อเลียน มันกลับมาเป็นโมฆะและฉันสมัครสมาชิกโมฆะนั้นซึ่งใช้ไม่ได้ ...

ข้อผิดพลาดกลับมา:

Failed to load ng:///DynamicTestModule/MockNodeDashboardComponent_Host.ngfactory.js: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

ฉันแก้ไขปัญหาโดยใช้ ts-mockito: https://github.com/NagRock/ts-mockito

ฉันเพิ่มรหัสเพื่อสร้างอินสแตนซ์จำลองเช่นนี้:

import { mock, instance, when } from 'ts-mockito';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { MockScenario } from './vcmts-api-client/model/MockScenario';

const MockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = mock(VcmtsnodemockresourceApi);
const obs = Observable.create((observer: Observer<MockScenario[]>) => {
  observer.next(new Array<MockScenario>());
  observer.complete();
});
when(MockVcmtsnodemockresourceApi.getMockScenariosUsingGET()).thenReturn(obs);
const instanceMockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = instance(MockVcmtsnodemockresourceApi);

จากนั้นเพิ่มอินสแตนซ์ไปยังอาร์เรย์ผู้ให้บริการของการทดสอบดังนี้:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      ...
      providers: [
        ...
        { provide: VcmtsnodemockresourceApi, useValue: instanceMockVcmtsnodemockresourceApi },
        ...
      ]        
    }).compileComponents();
  }));

หากคุณมีคำถามใหม่โปรดขอได้โดยคลิกที่ถามคำถามปุ่ม รวมลิงค์ไปยังคำถามนี้หากช่วยระบุบริบท - จากการรีวิว
Anton Balaniuc

ดูเหมือนว่าอาการของฉันจะเหมือนกับ OP ดังนั้นฉันคิดว่าผู้คนอาจมีประโยชน์ในการแก้ไขที่เหมาะกับฉัน ...
Datum Geek

3

ฉันประสบปัญหาเดียวกันและฉันพบว่าการแก้ไขคุณต้องตั้งค่าอินพุตของคุณสำหรับองค์ประกอบในวิธีการก่อนที่แต่ละด้านล่าง:

beforeEach(() => {
    fixture = TestBed.createComponent(CellComponent );
    cmp = fixture.debugElement.componentInstance;
    cmp.dep = '';
    cmp.embedded = false;
    cmp.dashboard = false;
    fixture.detectChanges();
});

วิธีนี้จะแก้ไขปัญหาของคุณได้อย่างแน่นอน


3

อาจเกี่ยวข้องกับ Chrome ซึ่งซ่อนข้อผิดพลาดในการทดสอบจริง พื้นที่ทดสอบจะทำให้โรงงาน http สับสนจำลองที่ไม่สามารถโหลดได้ดังนั้นจึงเป็นข้อผิดพลาดที่จะรายงาน ส่วนใหญ่ข้อผิดพลาดจะอยู่รอบ ๆ พื้นที่ ngOnInit ซึ่งเป็นวัตถุพูดคาดว่าวัตถุย่อยและพวกเขาจะไม่ได้กำหนด

หากต้องการลองไปที่ด้านล่างของข้อผิดพลาดให้เปลี่ยนเป็น PhantomJS เป็นการชั่วคราวซึ่งดูเหมือนว่าจะมีข้อผิดพลาดในการเริ่มต้นน้อยลงและหวังว่าจะรายงานข้อผิดพลาดจริงให้กับคุณ หลายครั้งที่ฉันพบว่าวัตถุที่คาดหวังจากการเริ่มต้นไม่สมบูรณ์ IE:

    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;

    component.object = {}
// should be:
    component.object = {"innerObjectThatIsNeeded" : []}

การแก้ไขวัตถุนั้นอนุญาตให้ PhantomJS ดำเนินการให้เสร็จสิ้นและ Chrome เพื่อไปยังการทดสอบถัดไป

นอกจากนั้นฉันไม่เห็นวิธีแก้ปัญหาในการลบปัญหาออกจาก Chrome เช่นเคยลองและนำนโยบาย "ลบรหัสออกไปจนกว่าข้อผิดพลาดจะเกิดขึ้น" เพื่อไล่ตามข้อผิดพลาด

UPDATE:โปรดทราบว่านี่เป็นคำตอบที่ค่อนข้างเก่าฉันไม่แนะนำให้ใช้ PhantomJS อีกต่อไป (EOL) การรายงานการทดสอบเบราว์เซอร์นั้นดีขึ้นมากและถ้า Chrome ให้ความเศร้าแก่คุณลอง Firefox ซึ่งก็จะทำการทดสอบได้ดีมากในปัจจุบัน


2

ฉันยังมีข้อผิดพลาดนี้ซึ่งความจริงที่จะบอกเป็นธรรมไม่ใช่ช่างพูด

มันเกี่ยวข้องกับการโทร HTTP ผ่านบริการของฉัน

ฉันใช้ myService.ts ด้วย 2 วิธี

get();
getAll();

ฉันเยาะเย้ยบริการนี้: mockMyService.ts

ข้อผิดพลาดเกิดขึ้นที่นี่เพราะส่วนประกอบของฉันใช้เมธอด getAll () ที่ฉันลืมนำไปใช้ใน mockMyService ดังนั้นฉันเพิ่งเพิ่มเมธอด:

private mockObjects = [
{
  'id': '1',
  'champ1': 'TECH',
  'champ2': 2,
  'champ3': 'Data bidon'
},
{
  'id': '2',
  'champ1': 'TECH',
  'champ2': 2,
  'champ3': 'Data au pif'
},
{
  'id': '3',
  'champ1': 'FUNC',
  'champ2': 3,
  'champ3': 'Data quelconque'
},
 ];

getAll(): Observable<any> {
  return Observable.of(this.mockObjects);
}

ข้อผิดพลาดหายไป :)


1

ในกรณีของฉันผู้กระทำผิดถูกobservable.timeout(x).retry(y)นำไปใช้ที่ไหนสักแห่งใน Observable ที่ส่งคืนในระดับบริการจากนั้นอีกครั้งในองค์ประกอบที่ใช้บริการนั้น

ทุกอย่างทำงานได้อย่างถูกต้องในเบราว์เซอร์จนถึง angi-cli 1.4 จากนั้นเริ่มล้มเหลวระหว่างการทดสอบ Karma (ด้วยข้อผิดพลาดโง่ ๆ ) วิธีการแก้ปัญหาแน่นอนเพื่อจัดระเบียบตัวดำเนินการหมดเวลา / ลองใหม่เหล่านี้


1

สำหรับฉันข้อความนี้จะปรากฏขึ้นเมื่อการเยาะเย้ยนั้นเป็นเท็จในการทดสอบของฉัน: โดยปกติคุณจะให้ mockService ในการทดสอบ bootstrap ของคุณ หากการเยาะเย้ยของคุณไม่สมบูรณ์หรือผิดพลาดจากนั้นมุมเชิงมุมจะส่งคืนข้อผิดพลาดโง่ ๆ นี้

ข้อมูลเพิ่มเติมเกี่ยวกับกรณีของฉันที่นี่


0

สิ่งที่ฉันจะทำคือ:

เพิ่ม console.log () s, บรรทัดหลังบรรทัดใน ngOnint () และค้นหาว่ามันไปไกลแค่ไหนจากนั้นตรวจสอบบรรทัดที่มันไม่ผ่าน

Ex:

ngOnInit() {
    this.route.paramMap
        .switchMap(params => {
            this.busy = true;
            this.updateErrors(null);

            console.log(params);

            **const id = params.get('id');**
            console.log(id);

            if (id === 'new') {
                this.editMode = true;
                return Observable.of(GroupComponent.newGroup());
            }
            return this.apiService.getGroup(id);
        })
    }

การทดสอบของฉันล้มเหลวโดยมีข้อผิดพลาดเดียวกันในโพสต์นี้ ดังที่แสดงไว้ข้างต้นฉันมีสอง console.logs คนแรกผ่านไปแล้ว แต่คนที่สองไม่ผ่าน ดังนั้นฉันจึงรู้ว่าปัญหาอยู่ที่ line const id = params.get ('id'); และฉันแก้ไขมัน

หวังว่านี่จะช่วยใครซักคน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.