异步测试确实会遍历所有功能
Async test does go trough all functions
当我尝试 运行 在 karma jasmine 中进行测试时,它应该通过 2 个服务。
然而,它一直执行到最后一个函数,但没有返回其 return 值。
有谁知道它为什么不 return 东西?
我的beforeEach
function checklistDbFactory(): PouchDB {
// ... is just for sharing
let db = new PouchDB("...");
PouchDB.plugin(PouchFind);
return db;
}
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [
{provide: CHECKLIST_DB, useFactory: checklistDbFactory, deps: []},
DatabaseService,
IndexService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
}
]
});
backend = TestBed.get(MockBackend);
service = TestBed.get(IndexService);
}));
我自己测试
it('function should return expectd json', async(() => {
backend.connections.subscribe(connection => {
connection.mockRespond(new Response(<ResponseOptions>{
body: JSON.stringify(expectJson)
}));
});
console.log("getting into main thread");
// ... is just for sharing
service.filldatabase(inputJson, "...").then((data) => {
console.log('getting into filldatabase');
console.log(data);
});
}));
填充数据库函数
filldatabase(jsonfile, key) {
console.log('Getting into filldatabase of 1service');
return this.databaseService.fillPouch(JSON.parse(jsonfile['_body']), key).then( (data) => {
console.log(data);
console.log("Getting into then of fillPouch in 1st service");
return true;
}).catch( () => {
console.log("getting into catch of fillpouch in 1service");
return false;
});
}
fillPouch 函数
fillPouch(json, key) {
json._id = key;
let push = this.db.put(
json
);
console.log("push");
console.log(push);
return push;
}
IntlliJ 测试输出
'getting into main thread'
'Getting into filldatabase of 1service'
'push'
ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
cmd 上的测试输出
✔ Service should be created
LOG: 'getting into main thread'
LOG: 'getting into main thread'
LOG: 'getting into main thread'
LOG: 'getting into main thread'
LOG: 'Getting into filldatabase of 1service'
LOG: 'Getting into filldatabase of 1service'
LOG: 'Getting into filldatabase of 1service'
LOG: 'Getting into filldatabase of 1service'
LOG: 'push'
LOG: 'push'
LOG: 'push'
LOG: 'push'
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
. ✔ function should return expectd json
// again file is just for sharing
31 10 2017 13:04:07.375:WARN [web-server]: 404: /assets/XML/<file>.json
LOG: 'Calling getJsonFromFile'
LOG: 'Calling getJsonFromFile'
LOG: 'Calling getJsonFromFile'
LOG: 'Calling getJsonFromFile'
这里也有一些奇怪的地方。 Calling getJsonFromFile
。在我的 app.component.ts 里面。但我不会在任何地方称呼它。
log所在的函数里面是
getData() {
this.databaseService.valueExist('checklistindex').then((data) => {
if(!data) {
console.log("Calling getJsonFromFile");
this.indexService.getJsonfromFile().subscribe((data) => {
console.log(JSON.stringify(data));
this.indexService.filldatabase(data,'checklistindex' );
})
}
})
}
如您所见,我确实完全进入了我的填充袋。但是它不会 return 推送。或沿线发生的任何事情。
Jasmine 支持异步测试,您需要接受一个额外的参数:
it('function should return expectd json', async((done) => { // <-- add this parameter
backend.connections.subscribe(connection => {
connection.mockRespond(new Response(<ResponseOptions>{
body: JSON.stringify(expectJson)
}));
});
console.log("getting into main thread");
// ... is just for sharing
service.filldatabase(inputJson, "...").then((data) => {
console.log('getting into filldatabase');
console.log(data);
done(); // <-- tell Jasmine you're finished
});
}));
传入的 done
函数在超时前给你五秒(默认情况下),如果你真的需要,你可以用 jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
更改它 - 虽然五秒相当已经很久了。
您可以对 beforeEach
、it
和 afterEach
使用 done
模式。
通过以正确的方式模拟我的数据服务解决了这个问题。
databaseServiceMock
import {DatabaseService} from "../../../../services/databaseService/databaseService";
export class DatabaseServiceMock extends DatabaseService {
constructor() {
super(null);
}
fillPouch(json, key) {
return Promise.resolve(true);
}
valueExist(key) {
return Promise.resolve(true);
}
getIndexVersion(key) {
return Promise.resolve("TRIAL VERSION v2");
}
}
通过模拟数据库服务,我也不得不在 TestBed
内部进行一些调整。
我以前每个现在
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [
{provide:DatabaseService, useClass: DatabaseServiceMock},
IndexService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
}
]
});
backend = TestBed.get(MockBackend);
service = TestBed.get(IndexService);
}));
我的测试看起来像
it('function should return expectd json', async(() => {
service.filldatabase(inputJson, "testpouch").then((data) => {
expect(data).toBeTruthy();
})
}));
这个问题的问题在于 this.db.put(json)
因为我没有模拟我的 databaseService 体面它没有在这里进一步。我稍微更改了 fillPouch 以使其更易于测试。
我的填充袋
fillPouch(json, key) {
json._id = key;
return this.db.put(json).then(() => {
return Promise.resolve(true);
}).catch((error) => {
return Promise.reject(false);
});
}
这一切都是用 PouchDB 完成的
当我尝试 运行 在 karma jasmine 中进行测试时,它应该通过 2 个服务。 然而,它一直执行到最后一个函数,但没有返回其 return 值。 有谁知道它为什么不 return 东西?
我的beforeEach
function checklistDbFactory(): PouchDB {
// ... is just for sharing
let db = new PouchDB("...");
PouchDB.plugin(PouchFind);
return db;
}
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [
{provide: CHECKLIST_DB, useFactory: checklistDbFactory, deps: []},
DatabaseService,
IndexService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
}
]
});
backend = TestBed.get(MockBackend);
service = TestBed.get(IndexService);
}));
我自己测试
it('function should return expectd json', async(() => {
backend.connections.subscribe(connection => {
connection.mockRespond(new Response(<ResponseOptions>{
body: JSON.stringify(expectJson)
}));
});
console.log("getting into main thread");
// ... is just for sharing
service.filldatabase(inputJson, "...").then((data) => {
console.log('getting into filldatabase');
console.log(data);
});
}));
填充数据库函数
filldatabase(jsonfile, key) {
console.log('Getting into filldatabase of 1service');
return this.databaseService.fillPouch(JSON.parse(jsonfile['_body']), key).then( (data) => {
console.log(data);
console.log("Getting into then of fillPouch in 1st service");
return true;
}).catch( () => {
console.log("getting into catch of fillpouch in 1service");
return false;
});
}
fillPouch 函数
fillPouch(json, key) {
json._id = key;
let push = this.db.put(
json
);
console.log("push");
console.log(push);
return push;
}
IntlliJ 测试输出
'getting into main thread'
'Getting into filldatabase of 1service'
'push'
ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
cmd 上的测试输出
✔ Service should be created
LOG: 'getting into main thread'
LOG: 'getting into main thread'
LOG: 'getting into main thread'
LOG: 'getting into main thread'
LOG: 'Getting into filldatabase of 1service'
LOG: 'Getting into filldatabase of 1service'
LOG: 'Getting into filldatabase of 1service'
LOG: 'Getting into filldatabase of 1service'
LOG: 'push'
LOG: 'push'
LOG: 'push'
LOG: 'push'
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
LOG: ZoneAwarePromise{__zone_symbol__state: null, __zone_symbol__value: []}
. ✔ function should return expectd json
// again file is just for sharing
31 10 2017 13:04:07.375:WARN [web-server]: 404: /assets/XML/<file>.json
LOG: 'Calling getJsonFromFile'
LOG: 'Calling getJsonFromFile'
LOG: 'Calling getJsonFromFile'
LOG: 'Calling getJsonFromFile'
这里也有一些奇怪的地方。 Calling getJsonFromFile
。在我的 app.component.ts 里面。但我不会在任何地方称呼它。
log所在的函数里面是
getData() {
this.databaseService.valueExist('checklistindex').then((data) => {
if(!data) {
console.log("Calling getJsonFromFile");
this.indexService.getJsonfromFile().subscribe((data) => {
console.log(JSON.stringify(data));
this.indexService.filldatabase(data,'checklistindex' );
})
}
})
}
如您所见,我确实完全进入了我的填充袋。但是它不会 return 推送。或沿线发生的任何事情。
Jasmine 支持异步测试,您需要接受一个额外的参数:
it('function should return expectd json', async((done) => { // <-- add this parameter
backend.connections.subscribe(connection => {
connection.mockRespond(new Response(<ResponseOptions>{
body: JSON.stringify(expectJson)
}));
});
console.log("getting into main thread");
// ... is just for sharing
service.filldatabase(inputJson, "...").then((data) => {
console.log('getting into filldatabase');
console.log(data);
done(); // <-- tell Jasmine you're finished
});
}));
传入的 done
函数在超时前给你五秒(默认情况下),如果你真的需要,你可以用 jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
更改它 - 虽然五秒相当已经很久了。
您可以对 beforeEach
、it
和 afterEach
使用 done
模式。
通过以正确的方式模拟我的数据服务解决了这个问题。
databaseServiceMock
import {DatabaseService} from "../../../../services/databaseService/databaseService";
export class DatabaseServiceMock extends DatabaseService {
constructor() {
super(null);
}
fillPouch(json, key) {
return Promise.resolve(true);
}
valueExist(key) {
return Promise.resolve(true);
}
getIndexVersion(key) {
return Promise.resolve("TRIAL VERSION v2");
}
}
通过模拟数据库服务,我也不得不在 TestBed
内部进行一些调整。
我以前每个现在
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [
{provide:DatabaseService, useClass: DatabaseServiceMock},
IndexService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
}
]
});
backend = TestBed.get(MockBackend);
service = TestBed.get(IndexService);
}));
我的测试看起来像
it('function should return expectd json', async(() => {
service.filldatabase(inputJson, "testpouch").then((data) => {
expect(data).toBeTruthy();
})
}));
这个问题的问题在于 this.db.put(json)
因为我没有模拟我的 databaseService 体面它没有在这里进一步。我稍微更改了 fillPouch 以使其更易于测试。
我的填充袋
fillPouch(json, key) {
json._id = key;
return this.db.put(json).then(() => {
return Promise.resolve(true);
}).catch((error) => {
return Promise.reject(false);
});
}
这一切都是用 PouchDB 完成的