Как тестировать устройство в соответствии с Угловой 2?

19

Проблема: Я хотел бы иметь возможность unit тестировать директиву в Angular 2, чтобы убедиться, что она правильно компилируется.

В «Угловом 1» можно было использовать услугу $compile(angular.element(myElement) и после этого вызвать $scope.$digest() . Я специально хочу, чтобы иметь возможность сделать это в модульных тестах, чтобы я мог проверить, что, когда Angular заканчивается на <div my-attr-directive/> в коде, который компилируется my-attr-directive .

Ограничения:

задан daniel.caspers 05.04.2016 в 18:47
источник
  • Вы используете TestComponentBuilder, как показано в выложенном SO-вопросе / ответе. Создайте тестовый компонент, в котором директива используется в шаблоне, а затем получите ссылку на директиву из созданного экземпляра тестового компонента. –  Günter Zöchbauer 05.04.2016 в 18:50
  • Спасибо за ответ. Просто понял, что вы ответили на этот вопрос раньше! Я подумал, что есть комментарий к этому вопросу относительно удаления поддержки TestComponentBuilder, когда он переместился в другой пакет, но я думаю, что я размываю сообщения SO в моем сознании. Благодарю. Я закрою это? –  daniel.caspers 05.04.2016 в 19:04

2 ответа

46

Тестирование скомпилированной директивы с использованием TestBed

Предположим, у вас есть следующая директива:

@Directive({
  selector: '[my-directive]',
})
class MyDirective {
  public directiveProperty = 'hi!';
}

Что вам нужно сделать, это создать компонент, который использует директиву (он может быть только для целей тестирования):

@Component({
  selector: 'my-test-component',
  template: ''
})
class TestComponent {}

Теперь вам нужно создать модуль, в котором они объявлены:

describe('App', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        TestComponent,
        MyDirective
      ]
    });
  });

  // ...

});

Вы можете добавить шаблон (содержащий директиву) к компоненту, но его можно обрабатывать динамически, перезаписывая шаблон в тесте:

it('should be able to test directive', async(() => {
  TestBed.overrideComponent(TestComponent, {
    set: {
      template: '<div my-directive></div>'
    }
  });

  // ...      

}));

Теперь вы можете попытаться скомпилировать компонент и запросить его с помощью By.directive . В самом конце есть возможность получить экземпляр директивы, используя injector :

TestBed.compileComponents().then(() => {
  const fixture = TestBed.createComponent(TestComponent);
  const directiveEl = fixture.debugElement.query(By.directive(MyDirective));
  expect(directiveEl).not.toBeNull();

  const directiveInstance = directiveEl.injector.get(MyDirective);
  expect(directiveInstance.directiveProperty).toBe('hi!');
}); 

# Старый ответ:

Чтобы проверить директиву, вам нужно создать поддельный компонент:

@Component({
  selector: 'test-cmp',
  directives: [MyAttrDirective],
  template: ''
})
class TestComponent {}

Вы можете добавить шаблон в самом компоненте, но его можно обрабатывать динамически, перезаписывая шаблон в тесте:

it('Should setup with conversation', inject([TestComponentBuilder], (testComponentBuilder: TestComponentBuilder) => {
    return testComponentBuilder
      .overrideTemplate(TestComponent, '<div my-attr-directive></div>')
      .createAsync(TestComponent)
      .then((fixture: ComponentFixture<TestComponent>) => {
        fixture.detectChanges();
        const directiveEl = fixture.debugElement.query(By.css('[my-attr-directive]'));
        expect(directiveEl.nativeElement).toBeDefined();
      });
  }));

Обратите внимание, что вы можете проверить, какие директивы визуализуются, но я не смог найти способ проверить директиву таким образом, чтобы компоненты (для директив не существует TestComponentBuilder).     

ответ дан Wojciech Kwiatek 07.06.2016 в 15:15
источник
  • Я получаю ошибку: нет провайдера DirectiveResolver, что может быть возможной причиной? –  Rahul Singh 16.03.2017 в 20:27
  • Чтобы использовать By, вам нужно будет импортировать {By} из '@ angular / platform-browser'; –  nottinhill 25.04.2017 в 18:14
  • как насчет того, что у diffective есть член @input ?, Мне интересно добавить модульный тест к этому элементу управления: github.com/czeckd/angular-dual-listbox .. но я не знаю, с чего начать. –  Rolando 07.05.2017 в 03:02
  • @Wojchieh - const directiveEl = fixture.debugElement.query (By.directive (MyDirective)); действительно полезно. Большой ответ –  Ryan 29.12.2017 в 15:24
  • Доступ к экземпляру директивы, хотя инжектор: Блестящий :) Я это запомню. благодаря –  maxime1992 07.06.2018 в 13:23
1

Пришло время найти хороший пример, хороший человек на угловом канале gitter указал мне посмотреть на репозиторий Angular Material Design 2 для примеров. Вы можете найти пример примера директивы здесь . Это тестовый файл для директивы tooltip Material Design 2. Похоже, вам нужно протестировать его как часть компонента.     

ответ дан Jusef 08.12.2016 в 00:44
источник
  • Прохладный ресурс! Спасибо, что поделился. Это не соответствует моим требованиям к вопросу о том, как быть JS-файлом. –  daniel.caspers 08.12.2016 в 04:53
  • Трудно найти какие-либо ресурсы в чистом JS. Одна из идей заключалась бы в том, чтобы получить репортаж материального дизайна, скомпилировать его и посмотреть на файл .js, который он создает. Я буду удивлен, насколько чистым является код JavaScript, созданный компилятором TypScript –  Jusef 08.12.2016 в 22:47
  • Трудно найти какие-либо ресурсы в чистом JS на данный момент. Одна из идей заключалась бы в том, чтобы получить репортаж материального дизайна, скомпилировать его и посмотреть на файл .js, который он создает. Вы будете удивлены тем, насколько чистым является код JavaScript, созданный компилятором TypScript –  Jusef 08.12.2016 в 22:51