[英]Angular 1.5 && Async/Await && jasmine tests
I already looked everywhere but could not find a solution yet for my particular case. 我已经到处寻找,但在我的特定情况下找不到解决方案。
We are using angular 1.5 and a Karma/Jasmine setup for unit tests. 我们使用angular 1.5和Karma / Jasmine设置进行单元测试。 In the initial source code, I used ES2017 async/await in the controller.
在初始源代码中,我在控制器中使用了ES2017 async / await。 That seemed to work fine as long as I added $apply of $digest manually at the end.
只要我最后手动添加$ apply of $ digest,这似乎工作得很好。 So for example:
例如:
async function loadData() {
try {
vm.isLoading = true;
vm.data = await DataService.getData();
$scope.$apply();
}
catch (ex) {
vm.isLoading = false;
}
}
To write an automated test for this particular function, I tried to mock DataService.getData with Jasmine's spyOn
. 为了编写这个特定函数的自动化测试,我尝试用Jasmine的
spyOn
模拟DataService.getData。 So, I did something like this: 所以,我做了这样的事情:
spyOn(DataService, 'getData').and.returnValue($q.when(fakeResult));
Adding the spy worked, but when running a test, the code seems to get struck and not resolve with fakeResult
. 添加间谍工作,但在运行测试时,代码似乎被触发,而不是使用
fakeResult
解决。 I tried adding $digest/$apply in the tests itself but could not fix it. 我尝试在测试中添加$ digest / $ apply但无法修复它。 I also did a lot of research, but still have no clue.
我也做了很多研究,但仍然没有任何线索。
Does somebody have a clue? 有人有线索吗?
Edit: testing the same method with $q
promises works fine, but I would really like to use async/await... 编辑:使用
$q
promises测试相同的方法工作正常,但我真的想使用async / await ...
I don't know if your setup is similar, but in our environment I had to do a couple of things to get transpiled async/await statements to resolve in jasmine tests. 我不知道你的设置是否相似,但在我们的环境中,我必须做一些事情才能在茉莉花测试中解析async / await语句来解决。
In our tests, I was trying to mock out services that would return promises. 在我们的测试中,我试图模拟可以返回承诺的服务。 I found that returning
$q.when
didn't work. 我发现返回
$q.when
不起作用。 Instead, I had to return actual A+ standard Promises. 相反,我必须返回实际的A +标准承诺。 My guess is that Angular's $q promises aren't fully complaint with the standard and wouldn't work as a substitute.
我的猜测是,Angular的$ q承诺并没有完全投诉该标准,也无法作为替代品。
Note that since we use PhantomJS for our tests, I had to add polyfills to get those Promises. 请注意,由于我们使用PhantomJS进行测试,因此我必须添加polyfill来获取这些Promise。
Many times in my tests I would have to wrap some of the expect statements in a setTimeout
block. 在我的测试中,我不得不在
setTimeout
块中包含一些expect语句。 Again, my assumption is that the promises need an additional "tick" to process. 同样,我的假设是承诺需要额外的“滴答”来处理。
So the reason why there is no result is because nothing after await
is executed. 所以没有结果的原因是因为
await
执行后没有任何结果。 I had a similar issue when I was testing async/await
inside react components. 当我在反应组件中测试
async/await
时,我遇到了类似的问题。 I found somewhere that a testing method for this is as follows: 我发现某个地方的测试方法如下:
DataService.getData()
, and use the .then()
method, where you can put your expect
statements - because of this step, your test is waiting for resolving the promise. DataService.getData()
,并使用.then()
方法,您可以在其中放置您的expect
语句 - 由于此步骤,您的测试正在等待解析promise。 Here is an example of my code (I am also using async
functions in tests): 这是我的代码示例(我也在测试中使用
async
函数):
it.async('should call `mySpecialMethod`', async () => {
const arrayToResolve = [ { data: 'data' } ];
const SomeService = context.SomeService;
spyOn(props, 'mySpecialMethod');
spyOn(SomeService, 'myMethodReturningPromise');
.and.returnValue(Promise.resolve(arrayToResolve));
//the method `myMethodReturningPromise` is called in componentDidMount
const wrapper = mount(<MyReactComponent {...props} />, context);
expect(SomeService.myMethodReturningPromise).toHaveBeenCalled();
//now I am calling the method again
await SomeService.myMethodReturningPromise();
//`mySpecialMethod` is calling after the `await` in my code
expect(props.mySpecialMethod).toHaveBeenCalled();
//after that I am changing the state
expect(wrapper.state().arrayToResolve).toEqual(arrayToResolve);
});
I hope this helps you :) 我希望这可以帮助你 :)
You can use the library async-await-jasmine : 您可以使用库async-await-jasmine :
import * as angular from 'angular';
import 'angular-mocks';
import {yourModule} from "./your-module-path";
import {LoadDataService} from './load-data';
import {$it} from "async-await-jasmine";
import {IRootScopeService} from "angular";
describe('Calculator', () => {
let $httpBackend: angular.IHttpBackendService;
beforeEach(() => {
angular.mock.module(calculatorModule.name);
angular.mock.inject((_$httpBackend_) => {
$httpBackend = _$httpBackend_;
});
});
$it('should loadData', async () => {
$httpBackend.when('GET', '/loadData').respond('{"value": 5}');
let sum = loadData(1, 4);
$httpBackend.flush();
expect(await sum).toBe(10);
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.