Angular5 TestBed useValue, кажется, не внедряет тот же экземпляр объекта - PullRequest
0 голосов
/ 19 сентября 2018

При написании модульных тестов я сталкиваюсь со странным случаем, для которого я не понимаю, в чем проблема.

Я подготовил короткий код для воспроизведения:

TestInjectable -простой инъецируемый класс

@Injectable()
class TestInjectable {
  testProperty = 'testValue';
}

TestComponent - небольшой компонент, использующий TestInjectable

@Component({
  providers: [TestInjectable],
  template: ''
})
class TestComponent {
  constructor(private injectable: TestInjectable) {
  }

  doTest() {
    return this.injectable.testProperty;
  }
}

Юнит-тест

describe('Test TestComponent', () => {
  beforeEach(async(() => {
    let testInjectableMock: TestInjectable = new TestInjectable();
    testInjectableMock.testProperty = 'valueInMock';

    TestBed.configureTestingModule({
      providers: [{provide: TestInjectable, useValue: testInjectableMock}],
      declarations: [TestComponent]
    }).compileComponents();
  }));

  it('should do something', () => {
    let fixture: ComponentFixture<TestComponent> = TestBed.createComponent(TestComponent);
    let component: TestComponent = fixture.componentInstance;

    expect(component.doTest()).toBe('valueInMock');
  });
});

Поскольку у меня есть testInjectableMock, для которого я установил valueInMock, я ожидал бы, что компонент вернет это значение.Проблема в том, что компонент возвращает testValue, которое является значением по умолчанию, и тест завершается неудачно с:

Ожидается, что 'testValue' будет 'valueInMock'.

Звучит какTestBed создает другой экземпляр TestInjectable, даже если я предоставил экземпляр с использованием свойства useValue.

providers: [{provide: TestInjectable, useValue: testInjectableMock}]

Кто-нибудь знает, пропустил ли я что-то или где улов и как убедить TestBedиспользовать макетный экземпляр?

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Я подозреваю, что даже с useValue вы не получаете незапятнанную версию вашего testInjectableMock.

Попробуйте это?

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [{provide: TestInjectable, useValue: new TestInjectable()}],
      declarations: [TestComponent]
    }).compileComponents().then(() => {
      const testInjectableMock = TestBed.get(TestInjectable);
      testInjectableMock.setTestProperty('valueInMock');
    });
  }));
0 голосов
/ 11 апреля 2019

Угловой DI клонирует объекты, предоставленные useValue, и, судя по всему, делает это неправильно:

https://github.com/angular/angular/issues/10788

Вместо этого следует использовать фабрику:

TestBed.configureTestingModule({
  providers: [{provide: TestInjectable, /*-->*/ useFactory: () => testInjectableMock}],
  declarations: [TestComponent]
}).compileComponents();
0 голосов
/ 19 сентября 2018

Попробуйте

describe('Test TestComponent', () => {
  let testInjectableMock: TestInjectable = new TestInjectable();

  beforeEach(async(() => {   
    TestBed.configureTestingModule({
      providers: [{provide: TestInjectable, useValue: testInjectableMock}],
      declarations: [TestComponent]
    }).compileComponents();
  }));

  it('should do something', () => {
    let fixture: ComponentFixture<TestComponent> = TestBed.createComponent(TestComponent);
    let component: TestComponent = fixture.componentInstance;
    testInjectableMock.testProperty = 'valueInMock';
    expect(component.doTest()).toBe('valueInMock');
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...