首页 > 解决方案 > 单元测试动态方法调用Angular

问题描述

我的组件中有这个服务,它的方法之一是动态调用的

@Input methodName: string;

constructor(
        private readonly testService: testService
    ) {
}

loadData() {
   this.testService[this.methodName]().subscribe();
}

一世

我在测试方法 loadData() 时遇到了很多麻烦,它一直告诉我 this.testService[methodName] 不起作用,你将如何测试这种方法?

it('should ',  fakeAsync(() => {
        // getData is the supposed methodName that has to be set;
        testService.getData.and.returnValue(asyncData({} as any));
        component.loadData();
        flush();
        expect(testService.getData).toHaveBeenCalled();
}));

标签: angulartypescriptunit-testingjasminekarma-jasmine

解决方案


  1. 在组件构造函数中制作服务public以进行更好的测试

  2. 将此示例作为标准做法:

服务.ts

@Injectable({
  providedIn: 'root',
})
export class UserSvcService {
  test() {
    return of('test');
  }
}

对于一个component.ts

@Component({
  selector: 'app-user-detail',
  templateUrl: './user-detail.component.html',
  styleUrls: ['./user-detail.component.scss'],
})
export class UserDetailComponent implements OnInit {
  name = 'test';
  val :string

  public constructor(public _userSvc: UserSvcService) {}

  ngOnInit() {
    this._userSvc[this.name]().subscribe(res =>
      this.val = res
    );
  }
}

创建一个像这样的存根:


export class UserServiceStub {
  test() {
    return of('test mock');
  }
}

用存根替换实际服务:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [],
      declarations: [UserDetailComponent],
      providers: [{ provide: UserSvcService, useClass: UserServiceStub }],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(UserDetailComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
    expect(component.val).toBe('test mock'); // move in another "it" block
  });

这应该有效。为了让您的工作方式,您需要创建一个spyOn以服务为public第一的:

it('should ',  () => {       
        spyOn(component.testService,'getData').and.returnValue(return of({some val}));
        component.loadData();
        expect(component.testService.getData).toHaveBeenCalled();
});

这篇文章可能会让你更感兴趣


推荐阅读