Angular 测试,为不同的测试用例动态改变 ActivatedRoute 参数

Posted

技术标签:

【中文标题】Angular 测试,为不同的测试用例动态改变 ActivatedRoute 参数【英文标题】:Angular Testing, dynamically change ActivatedRoute params for different test cases 【发布时间】:2019-01-27 05:05:07 【问题描述】:

组件:

@Component(
  selector: 'app-test',
  templateUrl: './test.component.html'
)
export class TestComponent implements OnInit 
  useCase: string;

  constructor(
    private route: ActivatedRoute,
  ) 

  ngOnInit() 
    this.route.queryParams.subscribe(p => 
      if (p) 
        this.useCase = p.u;
      
    );
  

测试规范

describe('TestComponent', () => 
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      imports: [
        AppModule
      ],
      providers: [
         provide: ActivatedRoute, useValue: ??? 
      ]
    )
      .compileComponents();
  ));

  beforeEach(() => 
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
  );

  it('should create', () => 
    expect(component).toBeTruthy();
    expect(component.useCase).toBeFalsy();
  );

  it('should set useCase variable with query string value', () => 
    fixture.detectChanges();
    // Set different route.queryParams here...
    expect(component.useCase).toBe('success');
  );
);

使用 Angular 6、Karma 和 Jasmine 进行单元测试。

我知道我们可以将ActivatedRoute 设置为将在整个测试过程中使用的对象,例如:

providers: [
   provide: ActivatedRoute, useValue: 
    queryParams: Observable.of(id: 123)
   
]

但这将为所有测试用例设置值。有没有办法在每个不同的测试用例中动态更改ActivatedRoute

【问题讨论】:

【参考方案1】:

如果您想将它存储在变量中,您可以在 it 函数中使用TestBed.get(ActivatedRoute) 来获取它。您也可以更新值。

从 Angular 最新版本的 Karma v9.0.0 开始,TestBed.get 方法已被弃用

【讨论】:

谢谢苏雷什!这样可行。就这么简单TestBed.get(ActivatedRoute).queryParams = of( id: 1 ); 你是个天才^^哈哈【参考方案2】:

如果你没有使用testBed,那么使用这行代码:

beforeEach 方法中,activatedRoute 模拟应定义如下:

activatedRoute = queryParams: of(id: 1);

然后在您的 it 方法中,将activatedRoute 更新为:

activatedRoute.queryParams = of(id: 2);

【讨论】:

【参考方案3】:

还有一个存根类的替代方案。按照下面的方法。

声明一个存根类

class ActivatedRouteStub 
    private _params = new Subject<any>();

    get params() 
        return this._params.asObservable();
    

    public push(value) 
        this._params.next(value);
    

在你的 beforeEach 中为激活的路由提供者声明一个别名

beforeEach(waitForAsync(() => 
        TestBed.configureTestingModule(
            imports: [
                RouterTestingModule
            ],
            declarations: [YourComponentComponent],
            providers: [
                
                    provide: ActivatedRoute,
                    useClass: ActivatedRouteStub
                
            ]
        )
            .compileComponents();
    ));

你可以在任何你想要的地方使用它。下面是“it”测试中的示例。

it('should show example, how to set parameters', () => 
        let spy = spyOn(router, 'navigate');
        
        // here we pass the any parameter for return and type the route variable with the stub class
        let route: ActivatedRouteStub = TestBed.inject<any>(ActivatedRoute);
        // you can push the parameters like you desire.
        route.push(id: 0)

        expect(spy).toHaveBeenCalledWith(['not-found'])
    );

【讨论】:

以上是关于Angular 测试,为不同的测试用例动态改变 ActivatedRoute 参数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 angular9 和 Jasmine 为所有组件生成 .pdf 格式的单元测试用例代码覆盖率报告

接口测试用例设计

如何写出高效的软件测试用例?微信朋友圈动态发送为例

如何在订阅Angular7单元测试用例中对代码进行单元测试

动态规划货币面值

在单元测试用例中模拟 Angular $window