Typescript 监视传入模拟节点模块的方法

Typescript 监视传入模拟节点模块的方法,typescript,unit-testing,jestjs,Typescript,Unit Testing,Jestjs,我正在构建一个客户机,它将包装signal库: export class RealTimeCommunicator { /** SignalR hub connection */ private hubConnection: HubConnection | null = null; private buildConnection(url: string): HubConnection { return new HubConnectionBuilder() .wit

我正在构建一个客户机,它将包装
signal
库:

export class RealTimeCommunicator {

  /** SignalR hub connection */
  private hubConnection: HubConnection | null = null;

  private buildConnection(url: string): HubConnection {
    return new HubConnectionBuilder()
    .withUrl(url)
    .build();
  }

  public subscribe(onStart: () => void, success: (data: IVehicleInfo) => void, fail?: (err: Error) => void): () => void {
    this.hubConnection = this.buildConnection("/someurl");
    this.hubConnection.on("send", data => {
      success(data);
    });

    this.hubConnection.start()
      .then(onStart)
      .catch(err => fail && fail(err));

    return this.unsubscribe;
  }

  public subscribeToVehicleDetails(vehicleId: number, success: (data: IVehicleInfo) => void, fail?: (err: Error) => void): () => void {
    return this.subscribe(() => this.hubConnection!.invoke("EnrolInVehicleGroupAsync", vehicleId), success, fail);
  }
我想测试它,但模拟了
signal
,因此我在解决方案中添加了
\uuuumocks\uuuu/@aspnet/signal.ts

let SignalR = jest.genMockFromModule("@aspnet/signalr");

class HubConnection {

  public on(methodName: string, callback: () => string): Promise<void> {
    this.successCallback = callback;
    return Promise.resolve()
  }

  public start(): Promise<void> { return Promise.resolve() }

  public successCallback: () => string = () => "failure";
}

let hubConnection = new HubConnection();

let HubConnectionBuilder = () => ({
  withUrl: (url) => ({
    build: () => hubConnection
  })
});

SignalR = {
  HubConnectionBuilder: HubConnectionBuilder,
  HubConnection: hubConnection
};

module.exports = SignalR;

如果我在我的
信号器中放置断点
mock,我可以看到
on
正在被调用,但是间谍没有看到它。另外,我连接到模拟上的
successCallback
将返回为
未定义的

您能否提供任何工作样本(例如以回购的形式)来重现您的问题?就我所见,所提供的代码片段中存在一些缺陷

首先,为什么是
jest.mock('signal')实际工作?信号器不是应该抛出错误的模块。您应该模拟实际导入的模块:
jest.mock(“@aspnet/signal”)。除此之外,测试的第一部分包括测试第三方库——为什么要这么做,除了检查您的模拟是否工作之外

其次,您要检查在创建间谍后是否立即调用了
on
方法。不过,间谍只会记录创建后发出的呼叫。您可能希望将on方法默认设置为spy:

// in __mocks__/@aspnet/signalr.ts

class HubConnection {

  public on = jest.fn().mockImplementation((methodName: string, callback: () => string) => {
    this.successCallback = callback;
    return Promise.resolve()
  });


  // ...

}

第三,您在测试中创建的连接与您稍后使用subscribeToVehicleDetails创建的连接不同,因此,如果成功回调可以正常工作,它仍然会返回“failure”。

如果成功,您只需要两个更改


返回
成功的结果(数据)

public subscribe(onStart:()=>void,success:(数据:IVehicleInfo)=>void,fail?:(err:Error)=>void):()=>void{
this.hubConnection=this.buildConnection(“/someurl”);
此.hubConnection.on(“发送”,数据=>{
返回成功(数据);//返回结果
});
this.hubConnection.start()
。然后(启动)
.catch(err=>fail&&fail(err));
退回此项。取消订阅;
}

等待断言已调用
spy
,直到调用
rtc.subscribetovehiledetails

constspy=jest.spyOn(连接,'on');
const successText=“成功!”;
const successCallBack:()=>string=()=>successText;
const rtc=新的RealTimeCommunicator();
rtc.subscribeToVehicleDetails(1,successCallBack,=>;
expect(spy).toHaveBeenCalled();//成功
expect(connection.successCallback()).toBe(successText);//成功
// in __mocks__/@aspnet/signalr.ts

class HubConnection {

  public on = jest.fn().mockImplementation((methodName: string, callback: () => string) => {
    this.successCallback = callback;
    return Promise.resolve()
  });


  // ...

}