- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个需要 jquery 的 ES6 模块。
import $ from 'jquery';
export class Weather {
/**
* Constructor for Weather class
*
* @param latitude
* @param longitude
*/
constructor(latitude, longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
/**
* Fetches the weather using API
*/
getWeather() {
return $.ajax({
url: 'http://localhost:8080/weather?lat=' + this.latitude + '&lon=' + this.longitude,
method: "GET",
}).promise();
}
}
模块在我的 main
模块中使用时工作正常,但问题出在我为它编写的测试上。
这是测试:
import {Weather} from '../js/weather';
import chai from 'chai';
import sinon from 'sinon';
chai.should();
describe('weatherbot', function() {
beforeEach(function() {
this.xhr = sinon.useFakeXMLHttpRequest();
this.requests = [];
this.xhr.onCreate = function(xhr) {
this.requests.push(xhr);
}.bind(this);
});
afterEach(function() {
this.xhr.restore();
});
it('should return a resolved promise if call is successful', (done) => {
let weather = new Weather(43.65967339999999, -79.72506369999999);
let data = '{"coord":{"lon":-79.73,"lat":43.66},"weather":[{"id":521,"main":"Rain","description":"shower rain","icon":"09d"}],"base":"stations","main":{"temp":15.28,"pressure":1009,"humidity":82,"temp_min":13,"temp_max":17},"visibility":24140,"wind":{"speed":7.2,"deg":30},"clouds":{"all":90},"dt":1496770020,"sys":{"type":1,"id":3722,"message":0.0047,"country":"CA","sunrise":1496741873,"sunset":1496797083},"id":5907364,"name":"Brampton","cod":200}';
weather.getWeather().then((data) => {
expect(data.main.temp).to.equal(15.28);
done();
});
this.requests[0].respond("GET", "/weather?lat=43.659673399999996&lon=-79.72506369999999", [
200, {"Content-Type":"application/json"}, JSON.stringify(data)
]);
});
});
这是我的package.json
:
{
"devDependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^6.1.0",
"babel-polyfill": "^6.3.14",
"babel-preset-es2015": "^6.1.18",
"chai": "^3.5.0",
"copy-webpack-plugin": "^0.2.0",
"css-loader": "^0.28.0",
"extract-text-webpack-plugin": "^2.1.0",
"file-loader": "^0.11.1",
"mocha": "^3.4.1",
"mocha-webpack": "^1.0.0-beta.1",
"qunitjs": "^2.3.2",
"sinon": "^2.2.0",
"style-loader": "^0.16.1",
"svg-inline-loader": "^0.7.1",
"webpack": "*",
"webpack-dev-server": "^1.12.1",
"webpack-node-externals": "^1.6.0"
},
"scripts": {
"build": "webpack",
"watch": "webpack --watch --display-error-details",
"start": "webpack-dev-server --hot --inline --port 8383",
"test": "mocha --compilers js:babel-core/register ./test/*.js",
"test:watch": "npm run test -- --watch"
},
"babel": {
"presets": [
"es2015"
]
},
"dependencies": {
"bootstrap": "^3.3.7",
"jquery": "^3.2.1",
"webpack": "*"
}
}
如您所见,我只需执行 npm test
即可运行测试。
当做 npm test
时,我得到这个错误:
TypeError: _jquery2.default.ajax is not a function
at Weather.getWeather (js/weather.js:19:18)
at Context.<anonymous> (test/index.js:26:17)
但是我正在模块中导入 jquery
,为什么会发生这种情况?
最佳答案
这里有两个主要问题。第一个当然是您需要解决导入问题,但这与测试无关。在进行测试之前,您需要解决这个问题,这可能与构建工具的配置和在 Node.js 中运行有关。你应该为此打开一个单独的问题,although this might be of help .可能您需要做的就是将导入替换为此 import * as jQuery from 'jquery';
另一个大问题是您在 Node 中运行它(使用触发 Mocha 的 npm test
),而您的代码需要浏览器。 Sinon 的假服务器实现旨在用于浏览器环境,而您正在服务器环境中运行测试。这意味着 jQuery 和伪造的服务器设置都不起作用,因为 Node 没有 XHR object .
因此,尽管 Sinon XHR 设置看起来不错,但除非您愿意更改测试运行器以在浏览器环境中运行测试(Karma 非常适合从 CLI 执行此操作!),否则您需要处理此问题用另一种方式。我很少去伪造 XHR,而是在更高层次上消除依赖关系。 @CarlMarkham 的回答涉及到这一点,但他没有详细说明这将如何与您的代码一起工作。
在 Node 中运行代码时,您基本上有两个选择:
ajax
stub 版本的对象。这需要一个模块加载器拦截器,例如 rewire
或 proxyquire
。诗乃主页有a good article by Morgan Roderick在第一个选项,以及几个links to other articles elsewhere on the net ,但没有说明如何执行第一个选项。当我有时间的时候我应该写一篇......但是这里是:
在实例级别使用依赖注入(inject)
侵入性最小的方法是只在您正在测试的实例上公开 ajax
方法。这意味着您不需要向模块本身注入(inject)任何东西,也不必考虑事后清理:
// weather.js
export class Weather {
constructor(latitude, longitude) {
this.ajax = $.ajax;
this.latitude = latitude;
this.longitude = longitude;
}
getWeather() {
return this.ajax({ ...
// weather.test.js
it('should return a resolved promise if call is successful', (done) => {
const weather = new Weather(43.65, -79.725);
const data = '{"coord":{"lon":-79.73, ... }' // fill in
weather.ajax = createStub(data);
我写了a more elaborate example of this technique on the Sinon issue跟踪器。
还有另一种方法,更具侵入性,但可以让您通过直接修改模块的依赖项来保持类代码不变:
在模块级别使用依赖注入(inject)
只需修改您的 Weather 类,为您的依赖项导出一个 setter 接口(interface),以便它们可以被覆盖:
export const __setDeps(jQuery) => $ = jQuery;
现在您可以将测试简化为如下所示:
import weather from '../js/weather';
const Weather = weather.Weather;
const fakeJquery = {};
weather.__setDeps(fakeQuery);
const createStub = data => () => { promise: Promise.resolve(data) };
it('should return a resolved promise if call is successful', (done) => {
const weather = new Weather(43.65, -79.725);
const data = '{"coord":{"lon":-79.73, ... }' // fill in
fakeQuery.ajax = createStub(data);
weather.getWeather().then((data) => {
expect(data.main.temp).to.equal(15.28);
done();
});
}
这种方法的一个问题是您正在篡改模块的内部结构,因此您需要恢复 jQuery 对象,以防您需要在其他测试中使用 Weather 类。当然,您也可以反过来做:您可以导出实际 jQuery 对象并直接修改ajax
方法,而不是注入(inject)伪造的jQuery 对象。然后,您将删除上面示例代码中的所有注入(inject)代码,并将其修改为类似于
// weather.js
export const __getDependencies() => { jquery: $ };
// weather.test.js
it('should return a resolved promise if call is successful', (done) => {
const weather = new Weather(43.65, -79.725);
const data = '{"coord":{"lon":-79.73, ... }' // fill in
__getDependencies().jquery.ajax = createStub(data);
// do test
// restore ajax on jQuery back to its original state
关于javascript - 如何测试需要 jquery 的 ES6 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44397639/
我获得了一些源代码示例,我想测试一些功能。不幸的是,我在执行程序时遇到问题: 11:41:31 [linqus@ottsrvafq1 example]$ javac -g test/test.jav
我想测试ggplot生成的两个图是否相同。一种选择是在绘图对象上使用all.equal,但我宁愿进行更艰巨的测试以确保它们相同,这似乎是identical()为我提供的东西。 但是,当我测试使用相同d
我确实使用 JUnit5 执行我的 Maven 测试,其中所有测试类都有 @ExtendWith({ProcessExtension.class}) 注释。如果是这种情况,此扩展必须根据特殊逻辑使测试
在开始使用 Node.js 开发有用的东西之前,您的流程是什么?您是否在 VowJS、Expresso 上创建测试?你使用 Selenium 测试吗?什么时候? 我有兴趣获得一个很好的工作流程来开发我
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 3 年前。 基于示例here ,我尝试为我的
我正在考虑测试一些 Vue.js 组件,作为 Laravel 应用程序的一部分。所以,我有一个在 Blade 模板中使用并生成 GET 的组件。在 mounted 期间请求生命周期钩子(Hook)。假
考虑以下程序: #include struct Test { int a; }; int main() { Test t=Test(); std::cout<
我目前的立场是:如果我使用 web 测试(在我的例子中可能是通过 VS.NET'08 测试工具和 WatiN)以及代码覆盖率和广泛的数据来彻底测试我的 ASP.NET 应用程序,我应该不需要编写单独的
我正在使用 C#、.NET 4.7 我有 3 个字符串,即。 [test.1, test.10, test.2] 我需要对它们进行排序以获得: test.1 test.2 test.10 我可能会得到
我有一个 ID 为“rv_list”的 RecyclerView。单击任何 RecyclerView 项目时,每个项目内都有一个可见的 id 为“star”的 View 。 我想用 expresso
我正在使用 Jest 和模拟器测试 Firebase 函数,尽管这些测试可能来自竞争条件。所谓 flakey,我的意思是有时它们会通过,有时不会,即使在同一台机器上也是如此。 测试和函数是用 Type
我在测试我与 typeahead.js ( https://github.com/angular-ui/bootstrap/blob/master/src/typeahead/typeahead.js
我正在尝试使用 Teamcity 自动运行测试,但似乎当代理编译项目时,它没有正确完成,因为当我运行运行测试之类的命令时,我收到以下错误: fatal error: 'Pushwoosh/PushNo
这是我第一次玩 cucumber ,还创建了一个测试和 API 的套件。我的问题是在测试 API 时是否需要运行它? 例如我脑子里有这个, 启动 express 服务器作为后台任务 然后当它启动时(我
我有我的主要应用程序项目,然后是我的测试的第二个项目。将所有类型的测试存储在该测试项目中是一种好的做法,还是应该将一些测试驻留在主应用程序项目中? 我应该在我的主项目中保留 POJO JUnit(测试
我正在努力弄清楚如何实现这个计数。模型是用户、测试、等级 用户 has_many 测试,测试 has_many 成绩。 每个等级都有一个计算分数(strong_pass、pass、fail、stron
我正在尝试测试一些涉及 OkHttp3 的下载代码,但不幸失败了。目标:测试 下载图像文件并验证其是否有效。平台:安卓。此代码可在生产环境中运行,但测试代码没有任何意义。 产品代码 class Fil
当我想为 iOS 运行 UI 测试时,我收到以下消息: SetUp : System.Exception : Unable to determine simulator version for X 堆
我正在使用 Firebase Remote Config 在 iOS 上设置 A/B 测试。 一切都已设置完毕,我正在 iOS 应用程序中读取服务器端默认值。 但是在多个模拟器上尝试,它们都读取了默认
[已编辑]:我已经用 promise 方式更改了我的代码。 我正在写 React with this starter 由 facebook 创建,我是测试方面的新手。 现在我有一个关于图像的组件,它有
我是一名优秀的程序员,十分优秀!