使用 jasmine 的 Angular 服务承诺响应测试

问题描述 投票:0回答:1

我创建了一个项目,它包含一个返回承诺布尔响应的服务。因此,我编写了规范代码来测试代码及其下降。错误如下,

预期“是”为“否”。

请帮助我确定我在测试承诺响应时所做的问题?。

代码示例如下。

服务

@Injectable({
  providedIn: "root"
})
export class CustomerService {
  constructor() {}

  isValid() : Promise<boolean> {
    return Promise.resolve(true);
  }
}

组件

@Component({
  selector: 'app-customer',
  templateUrl: './customer.component.html',
  styleUrls: ['./customer.component.scss']
})
export class CustomerComponent implements OnInit {
  icon = new BehaviorSubject('yes');
  constructor(private readonly customerService : CustomerService) {

  }

  ngOnInit(): void {
    this.customerService.isValid().then(isValid => {
      if(isValid){
        this.icon.next('yes');
      } else{
        this.icon.next('no');
      }
    });
  }
}

测试组件

describe('CustomerComponent', () => {
  let component: CustomerComponent;
  let fixture: ComponentFixture<CustomerComponent>;
  let customerServiceSpy: jasmine.SpyObj<CustomerService>;

  beforeEach(async () => {
    customerServiceSpy = jasmine.createSpyObj<CustomerService>(['isValid']);

    await TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule
      ],
      declarations: [
        CustomerComponent,
      ],
      providers: [
        { provide: CustomerService, useValue: customerServiceSpy },
      ]
    }).compileComponents();

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  fit('should change initial value of icon according to the response of isValid function', waitForAsync(() => {
    fixture.detectChanges();

    customerServiceSpy.isValid.and.returnValue(Promise.resolve(false));
    component.ngOnInit();

    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(component.icon.value).toBe('no');
    });

    customerServiceSpy.isValid.and.returnValue(Promise.resolve(true));
    component.ngOnInit();

    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(component.icon.value).toBe('yes');
    });
  }));
});
javascript angular rxjs jasmine angular15
1个回答
0
投票

将两个期望放到自己的测试中。 expect 在一个 promise 中,所以第二个间谍在运行 promise 中的代码之前运行。或者不是把你的期望放在承诺回调中,而是做

await fixture.whenStable();
所以所有代码都在承诺解决后运行。

const fixture = { whenStable: () => Promise.resolve(true) };

describe('promise', function() {
  let customerServiceSpy = jasmine.createSpyObj(['isValid']);
  
  it('fail', async () => {
    customerServiceSpy.isValid.and.returnValue(Promise.resolve('no'));
    
    fixture.whenStable().then(() => {
      // this code is running in a promise so it is queued to run after this whole block
      customerServiceSpy.isValid().then(isValid => { expect(isValid).toEqual('no'); })
    });
    
    // this runs before the code in the promise runs so overwrites the initial spy
    customerServiceSpy.isValid.and.returnValue(Promise.resolve('yes'));
  });
  
  it('pass', async () => {
    customerServiceSpy.isValid.and.returnValue(Promise.resolve('no'));
    
    fixture.whenStable().then(() => {
      customerServiceSpy.isValid().then(isValid => { expect(isValid).toEqual('no'); })
    });
  });
  
  it('pass with await', async () => {
    customerServiceSpy.isValid.and.returnValue(Promise.resolve('no'));
    
    await fixture.whenStable();
    
    // Promise has reolved so isValid still returns the no promise
    customerServiceSpy.isValid().then(isValid => { expect(isValid).toEqual('no'); })
        
    customerServiceSpy.isValid.and.returnValue(Promise.resolve('yes'));
  });
});
.snippet-result-code {
  height: 320px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/4.5.0/jasmine.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/4.5.0/jasmine-html.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/4.5.0/boot0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/4.5.0/boot1.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/4.5.0/jasmine.min.css" />

© www.soinside.com 2019 - 2024. All rights reserved.