অ্যাঙ্গুলার 2 এ ইভেন্টইমিটার পরীক্ষা করার কোনও উপায়?


88

আমার একটি উপাদান রয়েছে যা একটি ইভেন্টইমিটার ব্যবহার করে এবং পৃষ্ঠার কাউকে ক্লিক করা হলে ইভেন্টএমিটার ব্যবহার করা হয়। ইউনিট পরীক্ষার সময় আমি ইভেন্টইমিটারটি পর্যবেক্ষণ করতে এবং ইভেন্টইমিটার.নেক্সট () পদ্ধতিটি ট্রিগার করে এমন উপাদানটি ক্লিক করতে টেস্টকম্পোন্ট বিল্ডার ব্যবহার করতে এবং কী পাঠানো হয়েছে তা দেখার জন্য কি কোনও উপায় আছে?


আপনি কি কোনও প্লাঙ্কার সরবরাহ করতে পারেন যা আপনি যা চেষ্টা করেছেন তা দেখায়, তবে আমি অনুপস্থিত টুকরাগুলি যুক্ত করতে পারি।
গন্টার জ্যাচবাউয়ার

উত্তর:


212

আপনার পরীক্ষা হতে পারে:

it('should emit on click', () => {
   const fixture = TestBed.createComponent(MyComponent);
   // spy on event emitter
   const component = fixture.componentInstance; 
   spyOn(component.myEventEmitter, 'emit');

   // trigger the click
   const nativeElement = fixture.nativeElement;
   const button = nativeElement.querySelector('button');
   button.dispatchEvent(new Event('click'));

   fixture.detectChanges();

   expect(component.myEventEmitter.emit).toHaveBeenCalledWith('hello');
});

যখন আপনার উপাদান:

@Component({ ... })
class MyComponent {
  @Output myEventEmitter = new EventEmitter<string>();

  buttonClick() {
    this.myEventEmitter.emit('hello');
  }
}

4
যদি এটি কোনও অ্যাঙ্কর হয় যা আমি বোতামের পরিবর্তে ক্লিক করছি তবে ক্যোয়ারী নির্বাচকটি কি বোতামের পরিবর্তে কেবল একটি হবে? আমি ঠিক সেই উপাদানটির মতো কিছু ব্যবহার করছি, তবে 'প্রত্যাশা (মান) .toBe (' হ্যালো ');' কখনও রান হয় না। আমি ভাবছি যদি এটি হয় কারণ এটি পরিবর্তে অ্যাঙ্কর।
টালকিড 24

আমি সত্যিকারের ইমিটারের পরিবর্তে কোনও গুপ্তচর ব্যবহার করে পরীক্ষার ক্লিনার সাথে আমার উত্তর আপডেট করেছি এবং আমি মনে করি এটি কাজ করা উচিত (এটি আমার ইবুকের নমুনাগুলির জন্য আসলে আমি যা করি)।
cexbrayat

এটি দুর্দান্ত ধন্যবাদ কাজ করে! আমি ফ্রন্ট এন্ড ডেভলপমেন্টে নতুন, বিশেষত ইউনিট টেস্টিংয়ে এটি নতুন। এটি অনেক সাহায্য করে। আমি এমনকি স্পাইঅন ফাংশন বিদ্যমান জানি না।
টালকিড 24

যদি মাই কম্পোম্পোন্টটি মোড়ানোর জন্য কোনও টেস্টকম্পোনেন্ট ব্যবহার করে তবে আমি এটি কীভাবে পরীক্ষা করতে পারি? উদাহরণস্বরূপ, এইচটিএমএল = <my-component (myEventEmitter)="function($event)"></my-component>এবং পরীক্ষায় আমি এটি করি: tcb.overrideTemplate (টেস্ট কম্পোনেন্ট, এইচটিএমএল) .createAsync (টেস্ট কম্পোনেন্ট)
বেকোস

4
চমত্কার উত্তর - খুব সংক্ষিপ্ত এবং বিন্দু - একটি খুব দরকারী সাধারণ প্যাটার্ন
danday74

48

আপনি একটি গুপ্তচর ব্যবহার করতে পারেন, আপনার স্টাইল উপর নির্ভর করে। এখানে আপনি কীভাবে সহজেই গুপ্তচর ব্যবহার করবেন তা দেখার জন্য কীভাবে emitবরখাস্ত করা হচ্ছে কিনা তা এখানে ...

it('should emit on click', () => {
    spyOn(component.eventEmitter, 'emit');
    component.buttonClick();
    expect(component.eventEmitter.emit).toHaveBeenCalled();
    expect(component.eventEmitter.emit).toHaveBeenCalledWith('bar');
});

পূর্ববর্তী মন্তব্যে উল্লিখিত হিসাবে অ্যাসিঙ্ক বা ফেকএসিঙ্কের অপ্রয়োজনীয় ব্যবহার না করার উত্তরটি আমি আপডেট করেছি। এই উত্তরটি কৌণিক 9.1.7 হিসাবে একটি ভাল সমাধান হিসাবে রয়ে গেছে। যদি কিছু পরিবর্তন হয় তবে দয়া করে একটি মন্তব্য দিন এবং আমি এই উত্তরটি আপডেট করব। যারা মন্তব্য করেছেন / পরিচালনা করেছেন তাদের জন্য ধন্যবাদ।
জোশুয়া মাইকেল ওয়াগনার

আপনি expectকি প্রকৃত গুপ্তচর ( spyOn()কল ফলাফল ) করা উচিত নয়?
ইউরি

আমি স্পাইওনের পরে "घटक.বাটনক্লিক ()" মিস করেছি। এই সমাধানটি আমার সমস্যা সমাধান করেছে। অনেক ধন্যবাদ!
মুক্তা

2

আপনি ইমিটারটিতে সাবস্ক্রাইব করতে পারেন বা এটিতে আবদ্ধ হতে পারেন, এটি যদি @Output()হয় তবে প্যারেন্ট টেম্পলেটে এবং বন্ধনটি আপডেট করা হয়েছে কিনা তা প্যারেন্টের উপাদানটিতে পরীক্ষা করতে পারেন। আপনি একটি ক্লিক ইভেন্ট প্রেরণ করতে পারেন এবং তারপরে সাবস্ক্রিপশনটি চালিত হওয়া উচিত।


সুতরাং আমি যদি emitter.subscribe (ডেটা => {}) পছন্দ করি; কিভাবে আমি পরের () আউটপুট পেতে পারি?
টালকিড 24

হুবহু অথবা টেমপ্লেট TestComponentহয়েছে <my-component (someEmitter)="value=$event">(যেখানে someEmitterএকটি হল @Output()পরে) valueসম্পত্তির TextComponentপাঠানো ইভেন্টের সাথে আপডেট করা উচিত নয়।
গন্টার জ্যাচবাউয়ার

0

আমার নির্গত অ্যারের দৈর্ঘ্য পরীক্ষা করার প্রয়োজন ছিল I সুতরাং আমি অন্যান্য উত্তরগুলির উপরে এটি কীভাবে করেছি।

expect(component.myEmitter.emit).toHaveBeenCalledWith([anything(), anything()]);

0

যদিও সর্বাধিক ভোট প্রাপ্ত উত্তরগুলি কাজ করে, তারা ভাল পরীক্ষার অনুশীলন প্রদর্শন করে না, তাই আমি ভেবেছিলাম যে আমি কিছু বাস্তব উদাহরণ দিয়ে গন্টারের উত্তরটি প্রসারিত করব ।

আসুন কল্পনা করুন যে আমাদের নীচের সহজ উপাদান রয়েছে:

@Component({
  selector: 'my-demo',
  template: `
    <button (click)="buttonClicked()">Click Me!</button>
  `
})
export class DemoComponent {
  @Output() clicked = new EventEmitter<string>();

  constructor() { }

  buttonClicked(): void {
    this.clicked.emit('clicked!');
  }
}

উপাদানটি হ'ল পরীক্ষার অধীনে থাকা সিস্টেমটি, এর কিছু অংশে গুপ্তচরবৃত্তিগুলি এনক্যাপসুলেশনকে ভেঙে দেয়। কৌণিক উপাদান পরীক্ষাগুলিতে কেবল তিনটি বিষয় সম্পর্কে জানা উচিত:

  • ডোম (উদাহরণস্বরূপ অ্যাক্সেস করা fixture.nativeElement.querySelector);
  • @Inputএস এবং @Outputএস এর নাম ; এবং
  • সহযোগিতা সেবা (ডিআই সিস্টেমের মাধ্যমে ইনজেকশন করা)।

উদাহরণস্বরূপ প্রত্যক্ষ পদ্ধতিতে অনুরোধ করা বা উপাদানগুলির অংশগুলির গুপ্তচরবৃত্তি জড়িত যে কোনও কিছুই বাস্তবায়নের সাথে খুব ঘনিষ্ঠভাবে মিলিত হয় এবং রিফ্যাক্টরেটিংয়ের সাথে ঘর্ষণ যোগ করবে - পরীক্ষার দ্বিগুণ কেবলমাত্র সহযোগীদের জন্য ব্যবহার করা উচিত। এই ক্ষেত্রে, আমাদের কোনও সহযোগী না থাকায় আমাদের কোনও উপহাস, গুপ্তচর বা অন্যান্য পরীক্ষার দ্বিগুণ হওয়া উচিত নয় ।


এটি পরীক্ষা করার একটি উপায় হ'ল সরাসরি ইমেটারে সাবস্ক্রাইব করে, তারপরে ক্লিক অ্যাকশনটি চাওয়া ( ইনপুট এবং আউটপুট সহ উপাদানটি দেখুন ):

describe('DemoComponent', () => {
  let component: DemoComponent;
  let fixture: ComponentFixture<DemoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ DemoComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(DemoComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should emit when clicked', () => {
    let emitted: string;
    component.clicked.subscribe((event: string) => {
      emitted = event;
    });

    fixture.nativeElement.querySelector('button').click();

    expect(emitted).toBe('clicked!');
  });
});

যদিও এটি সরাসরি উপাদান উপাদানটির সাথে ইন্টারঅ্যাক্ট করে, এর নামটি @Outputপাবলিক এপিআইয়ের অংশ, সুতরাং এটি খুব শক্তভাবে মিলিত হয় না।


বিকল্পভাবে, আপনি একটি সাধারণ পরীক্ষা হোস্ট তৈরি করতে পারেন ( একটি পরীক্ষার হোস্টের অভ্যন্তর দেখুন ) এবং আসলে আপনার উপাদানটি মাউন্ট করতে পারেন:

@Component({
  selector: 'test-host',
  template: `
    <my-demo (clicked)="onClicked($event)"></my-demo>
  `
})
class TestHostComponent {
  lastClick = '';

  onClicked(value: string): void {
    this.lastClick = value;
  }
}

তারপরে প্রসঙ্গে উপাদানটির পরীক্ষা করুন:

describe('DemoComponent', () => {
  let component: TestHostComponent;
  let fixture: ComponentFixture<TestHostComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ TestHostComponent, DemoComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(TestHostComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should emit when clicked', () => {
    fixture.nativeElement.querySelector('button').click();

    expect(component.lastClick).toBe('clicked!');
  });
});

componentInstanceএখানে পরীক্ষা হোস্ট , তাই আমরা নিশ্চিত যে আমরা মাত্রাতিরিক্ত উপাদান আমরা আসলে পরীক্ষা করছি করার মিলিত করছি না হতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.