【问题标题】:How to mock a service without using TestBed如何在不使用 TestBed 的情况下模拟服务
【发布时间】:2018-02-01 07:24:54
【问题描述】:

我想在不触及外部模板的情况下为我的组件编写一些单元测试。但我不知道如何模拟我的组件所依赖的服务。

my-component.ts

@Component({
    selector: 'my-component',
    templateUrl: './my-component.component.html',
    styleUrls: ['./my-component.component.scss']
})
export class MyComponent {

    constructor(public service: AnotherService) {}

}

my-component.spec.ts

let component: MyComponent;

beforeEach(() => {
    myComponent = new MyComponent(null);
});

another.service.ts

@Injectable()
export class AnotherService {
    toto: string;
}

这可行,但我想模拟 AnotherService 而不是 null,所以我创建了一个模拟服务:

class AnotherServiceStub {
    toto: string
}

myComponent = new MyComponent(<AnotherService> new AnotherServiceStub());

但以 ActivatedRoute 为例,

component = new MyComponent(<ActivatedRoute> {});

不起作用。 Typescript 要求我将 ActivatedRoute 类的所有属性添加到我的模拟中,例如 urlparamsqueryParams 等。我该如何避免这种情况?

【问题讨论】:

  • myComponent = new MyComponent({ toto: 'something' });?
  • @jonrsharpe 谢谢,但它不起作用,因为我使用 Typescript,它检查参数的类型。
  • 如果您的模拟具有相同的签名,它将起作用。这与通过测试台的提供者注入模拟相同。你能举一个不那么抽象的例子吗?
  • 幸运的是,定义类型的不是TS,而是你。你可以欺骗它接受你需要的一切,new MyComponent(&lt;AnotherService&gt;{ toto: 'something' }) 甚至new MyComponent(&lt;AnotherService&gt;&lt;any&lt;{ toto: 'something' })
  • @estus 是的,{ toto: 'something' } 有效,谢谢。但是例如,当我更新我的问题 {} 时,Typescript 要求我将 ActivatedRoute 类的所有参数添加到我的模拟中,例如:url、params、queryParams 等。我怎样才能避免这种情况?

标签: angular unit-testing mocking components testbed


【解决方案1】:

完全符合原类接口的Service mocks可以按原样提供:

myComponent = new MyComponent(stub);

如果一个 mock 部分符合接口并且没有通过类型检查,则可以使用type assertion

myComponent = new MyComponent(<AnotherService>stub);

当类型完全不匹配时,可以使用双重断言:

myComponent = new MyComponent(<AnotherService><any>stub);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多