【问题标题】:How to test Angular Router Resolve methed?如何测试 Angular Router Resolve 方法?
【发布时间】:2021-10-08 09:08:36
【问题描述】:

我需要将单元测试写入 Angular 路由器解析器。 写了个创建单元测试,但是不知道怎么测试返回值,卡在里面了。

用于获取组件信息的解析器

@Injectable
export class InfoResolver implements Resolve<any> {
  constructor(private readonly http: HttpClient, private readonly store: Store<IAppState>) {}

  resolve(route: ActivatedRouteSnapshot): any {
    const a$ = this.store.pipe(select(a));
    const b$ = this.store.pipe(select(b));

    return combineLatest([a$, b$]).pipe(
      take(1),
      map(([a, b]) => {
        return a && !(b && route.paramMap.get(id) === 2)
          ? this.http.get('/url')
          : of(false)      
        })
    )
  }
}

用于创建解析器的单元测试

const state = {
  a: true,
  b: false
}

describe('InfoResolver', () => {
  let resolver: InfoResolver
  let route = {
    paramMap: {
      get: (id) => 1
    }
  }

  beforeEach(async() => {
    TestBed.configureTestingModule({
      providers: [InfoResolver, provideMockStore({ state })]
    })

    resolver = TestBed.inject(InfoResolver)
  })

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

如何测试resolve方法的返回值?

【问题讨论】:

    标签: angular unit-testing jasmine karma-jasmine karma-runner


    【解决方案1】:

    如果您要注入 HttpClient,则应该导入 HttpClientTestingModule,这样您实际上就不会在单元测试中进行 Http 调用。

    要进行单元测试,我会直接调用 resolve 方法并订阅它,如第二个测试所示。

    import { HttpClientTestingModule } from '@angular/common/http/testing';
    ....
    const state = {
      a: true,
      b: false
    }
    
    describe('InfoResolver', () => {
      let resolver: InfoResolver
      let route = {
        paramMap: {
          get: (id) => 1
        }
      }
    
      beforeEach(async() => {
        TestBed.configureTestingModule({
          // add this to imports array
          imports: [HttpClientTestingModule],
          providers: [InfoResolver, provideMockStore({ state })]
        })
    
        resolver = TestBed.inject(InfoResolver)
      })
    
      it('should create', () => {
        expect(resolver).toBeTruthy()
      })
    
      // new test
      it('should return xyz if abc', (done: DoneFn) => {
        resolver.resolve(route).subscribe(result => {
          expect(result).toBeTruthy();
          // do other assertions
          done(); // call done to tell jasmine you're done with the test
        });
      });
    })
    

    【讨论】:

      【解决方案2】:

      您已经安排了一个ActivatedRouteSnapshot 参数和一个模拟存储,剩下要做的就是安排一个模拟http,然后调用resolve 并订阅它。

      由于您的 observable 以同步方式运行,您可以在回调中安全地调用 expect 来进行断言(例如,假设 a 为真,b 为假且 id 为 1,resolve 返回的 observable 预计会发出您为模拟 http 设置的任何数据)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 2022-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多