开篇三问:
为何要进行单元测试?
单元测试有什么好处?
如何编写angular单元测试?
没有单元测试会如何?
或者换句话说,为何要开发编写单元测试?
在业务开发紧张的情况下,往往会忽略单元测试,直接采用,然后开启下方的难忘人生回忆~
单元测试有啥好处?
我们在开发完毕,加入单元测试环节,下划线部分可能就不存在了~
如何进行angular单元测试?
angular前提背景知识
- 构建angular框架,angular-cli命令可以,在创建service、pipe、component时候,同时创建对应的测试用例**.spec.ts文件
- 运行单元测试
ng test --no-watch --code-coverage //根目录下会生成coverage目录,其中index.html记录组件覆盖率
- 查看
编写angular8 单元测试
测试service-无依赖
框架new实例测试
代码如下:
@Injectable() //交给angular管理,帮忙注入依赖
export class ValueService {
value:string;
constructor() { }
getValue() { return this.value}
}
测试用例如下:
# 1.直接new service 实例
let service: ValueService;
beforeEach(() => { service = new ValueService(); });
it('#getValue should return real value', () => {
expect(service.getValue()).toBe('real value');
});
# or
# 2.直接获取服务实例进行测试,通过调用服务,校验逻辑
let service: ValueService;
beforeEach(() => {
TestBed.configureTestingModule({ providers: [ValueService] }); //等效于useClass
});
it('should use ValueService', () => {
service = TestBed.get(ValueService);
expect(service.getValue()).toBe('real value');
});
测试service - 有依赖
利用spyOn mock
代码如下:
@Injectable()
export class MasterService {
constructor(private valueService: ValueService) { }
getValue() { return this.valueService.getValue(); }
}
获取真实的依赖服务,常因为服务中依赖原因,难以顺利创建。此时spy,跳过真正的服务业务逻辑,进行单独测试,是最简单的方法。** 不跳过依赖,则属于集成测试范畴。**
测试如下:
let masterService: MasterService;
let valueServiceSpy: jasmine.SpyObj<ValueService>;
beforeEach(() => {
const spy = jasmine.createSpyObj('ValueService', ['getValue']);//需要注意位置,在beforeEach
TestBed.configureTestingModule({
// Provide both the service-to-test and its (spy) dependency
providers: [
MasterService,
//注入服务,mock提供依赖服务的支持,完成MasterService实例创建
{ provide: ValueService, useValue: spy }
]
});
// Inject both the service-to-test and its (spy) dependency
masterService = TestBed.get(MasterService);
valueServiceSpy = TestBed.get(ValueService);
});
it('#getValue should return stubbed value from a spy', () => {
const stubValue = 'stub value';
# mock 返回值
valueServiceSpy.getValue.and.returnValue(stubValue);
expect(masterService.getValue())
.toBe(stubValue, 'service returned stub value'); //利用mock依赖返回的值,进行期望判断业务逻辑
});
测试组件-无依赖
代码如下:
@Component({
selector: 'lightswitch-comp',
template: `
<button (click)="clicked()">Click me!</button>
<span>{
{message}}</span>`
})
export class LightswitchComponent {
isOn = false;
clicked() { this.isOn = !this.isOn; }
get message() { return `The light is ${this.isOn ? 'On' : 'Off'}`; }
}
测试代码如下:
//直接new
it('#clicked() should set #message to "is on"', () => {
const comp = new LightswitchComponent();
expect(comp.message).toMatch(/is off/i, 'off at first');
comp.clicked();
expect(comp.message).toMatch(/is on/i, 'on after clicked');
});
//or 获取组件实例,交给框架创建new
let comp:LightswitchComponent;
beforeEach(() => {
TestBed.configureTestingModule({
// provide the component-under-test and dependent service
providers: [
Lights