HTML не обновляется в угловых тестах при внесении изменений в сервис - PullRequest
0 голосов
/ 09 мая 2018

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

В компоненте:

get me() {
  return this.sessionService.getMe()
}

В html компонента:

<a id="profile-button" *ngIf="me.loggedIn" routerLink="profile">Profile</a>

Мне нужно проверить, отображается ли кнопка, когда я вошел в систему, и что она не отображается, когда я не вошел в систему. Я отключаю службу сеанса следующим образом:

В файле спецификации компонента:

let sessionServiceStub = {
  currentUser: {
    loggedIn: false
  }

  getMe: function () {
    return this.currentUser
  }
}

beforeEach(async(() => {
  TestBed.configureTestingModule({
    imports: ['RouterTestingModule'],
    declarations: ['MyComponent'],
    providers: [{provide: SessionService, useValue: sessionServiceStub}],
  }).compileComponents()
}))

beforeEach(() => {
  sessionServiceStub.currentUser = {
    loggedIn = false
  }

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

В начале каждого теста я устанавливаю свойство loggedOn в заглушке сервиса на true или false, затем вызываю detectChanges(), но HTML-код не обновляется должным образом. Связано ли это с геттером, и если да, как я могу заставить представление получить новое значение из sessionService?

В файле спецификации компонента:

it('shows the button when a user is logged in', () => {
  sessionServiceStub.currentUser.loggedIn = true
  fixture.detectChanges()

  de = fixture.debugElement.query(By.css('#profile-button'))
  el: HTMLAnchorElement = de.nativeElement // TypeError: Cannot read property 'nativeElement' of null
  // ...
})

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

Вы можете использовать следующий подход: describe функции могут быть вложены в другие describe функции. Это дает вам возможность структурировать ваши тесты в несколько разделов, которые будут разделять общую плиту котла, следующим образом.

Предупреждение: следующий код является строго информативным и не был проверен.

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: ['RouterTestingModule'],
      declarations: ['MyComponent'],
      providers: [{provide: SessionService, useValue: sessionServiceStub}],
    }).compileComponents()
  }))

  describe('when user is connected', () => {
    beforeEach(() => {
      sessionServiceStub.currentUser.loggedIn = true
      fixture = TestBed.createComponent(MyComponent)
      component = fixture.componentInstance
      fixture.detectChanges()
    })

    it('shows the button when a user is logged in', () => {
      de = fixture.debugElement.query(By.css('#profile-button'))
      el: HTMLAnchorElement = de.nativeElement
      // ...
    })
  })

  describe('when user is NOT connected', () => {
    beforeEach(() => {
      sessionServiceStub.currentUser.loggedIn = false
      fixture = TestBed.createComponent(MyComponent)
      component = fixture.componentInstance
      fixture.detectChanges()
    })
  })

  it('does NOT show the button when a user is NOT logged in', () => {
    de = fixture.debugElement.query(By.css('#profile-button'))
    el: HTMLAnchorElement = de.nativeElement
    // ...
  })
})

Этот подход немного сложнее на первом сайте, чем тот, который вы выбрали. Тем не менее, он имеет несколько преимуществ:

  1. Вложенные функции describe создают различные контексты в ваших тестах: " пользователь вошел в систему " vs " пользователь не вошел в систему ". Это помогает объединить котельные плиты для испытаний в одном контексте.

  2. Следовательно, он разделяет абсолютно разные тестовые случаи в вашем файле.

  3. Он использует функции beforeEach для настройки контекста (« пользователь вошел в систему », « пользователь не вошел в систему »), где он должен быть, вместо того, чтобы делать это «на лету», в it функциях, где может быть трудно обнаружить других разработчиков (даже для себя через несколько дней).

0 голосов
/ 10 мая 2018

При добавлении sessionServiceStub в массив провайдеров для тестов создается новый экземпляр. После создания экземпляра я модифицировал исходную заглушку, и эти изменения были недоступны до следующих тестов (когда был создан новый экземпляр).

При удалении currentUser из заглушки все внесенные в него изменения все равно будут доступны для тестов, поскольку новый экземпляр будет ссылаться на тот же объект currentUser.

let currentUser: {
  loggedIn: false
}

let sessionServiceStub = {


  getMe: function () {
    return currentUser
  }
}
0 голосов
/ 09 мая 2018

Удалите fixture.detectChanges () из метода beforeEach.

beforeEach(() => {
  sessionServiceStub.currentUser = {
    loggedIn = false
  }

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

})

Должно работать нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...