Angular 角茉莉花测试,模拟分解器,用于带防护分解器的路由

Angular 角茉莉花测试,模拟分解器,用于带防护分解器的路由,angular,jasmine,Angular,Jasmine,我有一个带有几个延迟加载模块的应用程序,每个模块都有自己的路由模块。我希望围绕每个路由模块编写一些测试,以防止对其路由的破坏性更改 我的计划是从测试中的路由模块导出路由,并将它们导入我的规范中的RouterTestingModule,然后模拟出所需的任何东西,如解析器、服务等 1)在我的示例中,由于某种原因,它似乎没有使用我创建的模拟解析程序,我将得到一个与尝试解析实际解析程序相关的错误 2)这是正确的方法吗?我看到的大多数示例都倾向于在测试中直接向RouterTestingModule提供路由

我有一个带有几个延迟加载模块的应用程序,每个模块都有自己的路由模块。我希望围绕每个路由模块编写一些测试,以防止对其路由的破坏性更改

我的计划是从测试中的路由模块导出路由,并将它们导入我的规范中的RouterTestingModule,然后模拟出所需的任何东西,如解析器、服务等

1)在我的示例中,由于某种原因,它似乎没有使用我创建的模拟解析程序,我将得到一个与尝试解析实际解析程序相关的错误

2)这是正确的方法吗?我看到的大多数示例都倾向于在测试中直接向RouterTestingModule提供路由,但我看不出这将如何防止对实际路由模块的破坏性更改,我只是简单地将其路由复制到测试中

帐户路由.module.ts

...
export const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'account/:id',
        component: AccountDetailComponent,
        resolve: { campaign: AccountResolver },
      },
    ]
  },
];
@Injectable()
export class MockAccountResolver implements Resolve<Account> {

  constructor() { }

  resolve() : Observable<Account>{

    let account = new Account();

    return of(account);
  }
}

beforeEach(() => {

      TestBed.configureTestingModule({
        imports: [RouterTestingModule.withRoutes(routes)],
        declarations: [AccountDetailComponent],

        // also tried providers: [ { provide: AccountResolver, usevalue: new MockAccountResolver()}]
        providers: [ AccountResolver,  MockAccountResolver]
      });
  
      router = TestBed.get(Router);
      location = TestBed.get(Location);
  
      router.initialNavigation();
    });
    
   // Test 1
   it('navigate to "" redirects you to /', fakeAsync(() => {
      router.navigate([""]).then(() => {
        expect(location.path()).toBe("/");
      });
    }));
    
    // Test 2
    it('navigate to ":id" redirects you to /1', fakeAsync(() => {
        router.navigate(["/account/1"]).then(() => {
          expect(location.path()).toBe("/account/1");
        });
    }));
帐户路由.module.spec.ts

...
export const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'account/:id',
        component: AccountDetailComponent,
        resolve: { campaign: AccountResolver },
      },
    ]
  },
];
@Injectable()
export class MockAccountResolver implements Resolve<Account> {

  constructor() { }

  resolve() : Observable<Account>{

    let account = new Account();

    return of(account);
  }
}

beforeEach(() => {

      TestBed.configureTestingModule({
        imports: [RouterTestingModule.withRoutes(routes)],
        declarations: [AccountDetailComponent],

        // also tried providers: [ { provide: AccountResolver, usevalue: new MockAccountResolver()}]
        providers: [ AccountResolver,  MockAccountResolver]
      });
  
      router = TestBed.get(Router);
      location = TestBed.get(Location);
  
      router.initialNavigation();
    });
    
   // Test 1
   it('navigate to "" redirects you to /', fakeAsync(() => {
      router.navigate([""]).then(() => {
        expect(location.path()).toBe("/");
      });
    }));
    
    // Test 2
    it('navigate to ":id" redirects you to /1', fakeAsync(() => {
        router.navigate(["/account/1"]).then(() => {
          expect(location.path()).toBe("/account/1");
        });
    }));
@Injectable()
导出类MockAccountResolver实现解析{
构造函数(){}
resolve():可观察{
let account=新帐户();
归还(账户);
}
}
在每个之前(()=>{
TestBed.configureTestingModule({
导入:[RouterTestingModule.withRoutes(路由)],
声明:[AccountDetailComponent],
//还尝试了提供程序:[{提供:AccountResolver,usevalue:new-MockAccountResolver()}]
提供程序:[AccountResolver,MockAccountResolver]
});
路由器=测试台.get(路由器);
location=TestBed.get(位置);
router.initialNavigation();
});
//测试1
它('navigate to''将您重定向到/',fakeAsync(()=>{
路由器。导航([“”])。然后(()=>{
预期(location.path()).toBe(“/”);
});
}));
//测试2
它('导航到“:id”将您重定向到/1',fakeAsync(()=>{
路由器。导航([“/account/1]”)。然后(()=>{
expect(location.path()).toBe(“/account/1”);
});
}));
测试1将通过,测试2将给出一个错误:

错误:未捕获(承诺中):NullInjectorError:R3InjectorError(DynamicTestModule)[AccountResolver->AccountService->ApiService->ApiService]:
NullInjectorError:没有ApiService的提供程序

像这样添加提供程序行:

提供程序:[{提供:AccountResolver,useClass:MockAccountResolver}]

然后在测试2中添加一个flush()语句,一切正常