测试导致未定义值的承诺
testing promises causing undefined values
我在测试我的代码时遇到此错误:
1) Sourcerer Testing: getStatusCode :
Error: Expected undefined to equal 200
我不确定为什么我在测试中得到 undefined
但当我 运行 代码时我得到 200
。可能是因为没有正确处理 promises
Test code:
import expect from 'expect';
import rp from 'request-promise';
import Sourcerer from './sourcerer';
describe("Sourcerer Testing: ", () => {
let sourcerer = new Sourcerer(null);
const testCases = {
"https://www.google.com": 200,
// "www.google.com":
};
describe("getStatusCode", () => {
it("", () => {
for (let testCase in testCases) {
sourcerer.setSourcererUrl(testCase);
expect(sourcerer.url).toEqual(testCase);
expect(sourcerer.getStatusCode()).toEqual(testCases[testCase]);
}
});
});
});
代码:
import rp from 'request-promise';
export default class Sourcerer {
constructor(url) {
this.options = {
method: 'GET',
url,
resolveWithFullResponse: true
};
this.payload = {};
}
setSourcererUrl(url) {
this.url = url;
}
getSourcererUrl() {
return this.url;
}
analyzeSourcePage() {
rp(this.options).then((res) => {
console.log(res);
}).catch((err) => {
console.log("ERROR");
throw(err);
});
}
getStatusCode() {
rp(this.options).then((res) => {
console.log(res.statusCode);
return res.statusCode;
}).catch((err) => {
console.log("STATUS CODE ERROR");
return 0;
});
}
}
免责声明:我不会 运行 在单个 it() 中使用 for 循环,因为我想知道哪个迭代失败了。当然有办法实现这一目标,但那是另一回事了。此外,这在很大程度上取决于您的测试 运行ner,但这里有一些我认为有用的经验法则。
但是对于您所要求的,在承诺得到解决之前,测试不应评估。有时(例如在 mocha 中),这意味着从 it() 内部函数返回承诺。有时,这意味着获得一个完成的函数并在您准备好进行测试评估时调用它。如果您提供有关测试框架的更多信息,我可能会提供帮助(其他人当然会)
getStatusCode
没有 return 任何东西。它应该 return 一个承诺:
getStatusCode() {
return rp(this.options)...
}
规范在这种情况下会失败,因为它期望 promise 对象等于 200。
它甚至更复杂,因为规范是异步的,并且在规范完成之前应该等待几个承诺。应该是这样的
it("", () => {
let promises = [];
for (let testCase in testCases) {
sourcerer.setSourcererUrl(testCase);
let statusCodePromise = sourcerer.getStatusCode()
.then((statusCode) => {
expect(sourcerer.url).toEqual(testCase);
expect(statusCode).toEqual(testCases[testCase]);
})
.catch((err) => {
throw err;
});
promises.push(statusCodePromise);
}
return promises;
});
co
提供了一个很棒的替代 Promise.all
的流量控制:
it("", co.wrap(function* () {
for (let testCase in testCases) {
sourcerer.setSourcererUrl(testCase);
expect(sourcerer.url).toEqual(testCase);
let statusCode = yield sourcerer.getStatusCode();
expect(statusCode).toEqual(testCases[testCase]);
}
});
我在测试我的代码时遇到此错误:
1) Sourcerer Testing: getStatusCode :
Error: Expected undefined to equal 200
我不确定为什么我在测试中得到 undefined
但当我 运行 代码时我得到 200
。可能是因为没有正确处理 promises
Test code:
import expect from 'expect';
import rp from 'request-promise';
import Sourcerer from './sourcerer';
describe("Sourcerer Testing: ", () => {
let sourcerer = new Sourcerer(null);
const testCases = {
"https://www.google.com": 200,
// "www.google.com":
};
describe("getStatusCode", () => {
it("", () => {
for (let testCase in testCases) {
sourcerer.setSourcererUrl(testCase);
expect(sourcerer.url).toEqual(testCase);
expect(sourcerer.getStatusCode()).toEqual(testCases[testCase]);
}
});
});
});
代码:
import rp from 'request-promise';
export default class Sourcerer {
constructor(url) {
this.options = {
method: 'GET',
url,
resolveWithFullResponse: true
};
this.payload = {};
}
setSourcererUrl(url) {
this.url = url;
}
getSourcererUrl() {
return this.url;
}
analyzeSourcePage() {
rp(this.options).then((res) => {
console.log(res);
}).catch((err) => {
console.log("ERROR");
throw(err);
});
}
getStatusCode() {
rp(this.options).then((res) => {
console.log(res.statusCode);
return res.statusCode;
}).catch((err) => {
console.log("STATUS CODE ERROR");
return 0;
});
}
}
免责声明:我不会 运行 在单个 it() 中使用 for 循环,因为我想知道哪个迭代失败了。当然有办法实现这一目标,但那是另一回事了。此外,这在很大程度上取决于您的测试 运行ner,但这里有一些我认为有用的经验法则。
但是对于您所要求的,在承诺得到解决之前,测试不应评估。有时(例如在 mocha 中),这意味着从 it() 内部函数返回承诺。有时,这意味着获得一个完成的函数并在您准备好进行测试评估时调用它。如果您提供有关测试框架的更多信息,我可能会提供帮助(其他人当然会)
getStatusCode
没有 return 任何东西。它应该 return 一个承诺:
getStatusCode() {
return rp(this.options)...
}
规范在这种情况下会失败,因为它期望 promise 对象等于 200。
它甚至更复杂,因为规范是异步的,并且在规范完成之前应该等待几个承诺。应该是这样的
it("", () => {
let promises = [];
for (let testCase in testCases) {
sourcerer.setSourcererUrl(testCase);
let statusCodePromise = sourcerer.getStatusCode()
.then((statusCode) => {
expect(sourcerer.url).toEqual(testCase);
expect(statusCode).toEqual(testCases[testCase]);
})
.catch((err) => {
throw err;
});
promises.push(statusCodePromise);
}
return promises;
});
co
提供了一个很棒的替代 Promise.all
的流量控制:
it("", co.wrap(function* () {
for (let testCase in testCases) {
sourcerer.setSourcererUrl(testCase);
expect(sourcerer.url).toEqual(testCase);
let statusCode = yield sourcerer.getStatusCode();
expect(statusCode).toEqual(testCases[testCase]);
}
});