2017-04-13 89 views
0

在我的代码中,我有一个方法返回一个零件对象,但它返回setTimeout方法中的对象。当我试图测试这个时,我遇到了这样的问题,即测试不会等待超时完成,然后才会评估该方法的响应。如何在测试期望之前告诉测试等待超时完成?Angular 2 Jasmine在继续之前等待超时

正如你所看到的getIntersection方法在超时时间内返回this.part。

public getIntersection(payload: DropPayload): Part { 
    let rect: ClientRect = this.element.nativeElement.getBoundingClientRect(); 
    if (rect.left < payload.event.pageX && rect.right > payload.event.pageX && rect.top < payload.event.pageY && rect.bottom > payload.event.pageY) { 
    setTimeout(() => { 
     this.changeRef.detectChanges(); 
     return this.part; 
    }); 
    } 
    return null; 
} 

这里的一些事情我已经基于研究这个问题的尝试,他们没有工作:

1:

it('return the part if the payload coordinates are inside the bounding box', async((done) => { 
    partInstance.part = Clone.create(mockPart); 
    let result: any = partInstance.getIntersection(mockPayload); 
    setTimeout(() => { 
    expect(result).toEqual(mockPart); 
    done(); 
    }); 
})); 

2:

it('return the part if the payload coordinates are inside the bounding box', async(() => { 
    partInstance.part = Clone.create(mockPart); 
    let result: any = partInstance.getIntersection(mockPayload); 
    setTimeout(() => { 
    expect(result).toEqual(mockPart); 
    }); 
})); 

3: (这个抛出的错误是runs没有定义,我相信这是一个Angular 1的解决方案)

it('return the part if the payload coordinates are inside the bounding box',() => { 
    let done: boolean = false; 
    let result: any; 
    runs(() => { 
    partInstance.part = Clone.create(mockPart); 
    result = partInstance.getIntersection(mockPayload); 
    setTimeout(() => { 
     done = true; 
    }); 
    }); 
    waitsFor(() => { 
    return done; 
    }); 
    runs(() => { 
     expect(result).toEqual(mockPart); 
    }); 
}); 

4:

it('return the part if the payload coordinates are inside the bounding box',() => { 
    partInstance.part = Clone.create(mockPart); 
    let result: any = partInstance.getIntersection(mockPayload); 
    setTimeout(() => { 
    expect(result).toEqual(mockPart); 
    }); 
}); 

回答

0

看看你的逻辑

public getIntersection(payload: DropPayload): Part { 
    let rect: ClientRect = this.element.nativeElement.getBoundingClientRect(); 
    if (rect.left < payload.event.pageX && rect.right > payload.event.pageX && rect.top < payload.event.pageY && rect.bottom > payload.event.pageY) { 
    setTimeout(() => { 
     this.changeRef.detectChanges(); 
     return this.part; 
    }); 
    } 
    return null; 
} 

两件事情:

  1. setTimeout异步发生。但主函数的返回是同步发生的。返回值将始终为空

  2. 返回setTimeout的回调没有达到您认为的效果,即奇迹般地使返回值变为其他值。回调返回的内容不是主函数的返回值是什么。

您需要重构您的代码,也许使用承诺。有方法返回一个承诺

public getIntersection(payload: DropPayload): Promise<Part> { 
    let rect: ClientRect = this.element.nativeElement.getBoundingClientRect(); 

    return new Promise((resolve) => { 
    setTimeout(() => { 
     this.changeRef.detectChanges(); 
     resolve(this.part); 
    }) 
    }) 
} 

我不知道你的方法背后的逻辑是对的,所以我刚刚离开它。但是您可能需要以某种方式将其合并回去。

然后就可以调用像

getIntersection().then(part => { 
    expect(...) 
}) 

功能使用您尝试与角async应该为此努力。