修改后无法在规范中看到更新的 DOM
unable to see the updated DOM in spec after its getting modified
我正在使用 Mocha/JSDOM 编写功能规范并使用 'chai' 断言。
用例是当我调用函数时:updateContent,
- 它会在内部调用另一个函数来获取一些 HTML 内容。
- 稍后我会处理 HTML 内容并将其添加到现有的 DOM 元素中。
当我在服务器上 运行 时,这工作正常,但问题是当我尝试编写规范时,无法看到更新的 DOM。我通过放置控制台语句检查了 updateContent 函数,我看到了更新的内容,但是一旦控制转移到 spec 函数,我看到原始的 DOM 添加到 JSDOM.
这是使用 Typescript、js 组合编写的,JQuery 用于 DOM 操作
你能帮我解决一下我在这里遗漏了什么吗?任何 suggestion/info 都会有所帮助。
我在访问
时尝试使用全局
updateContent 函数在 helper.js 文件
中可用
function updateContent(year, fetchAge) {
Promise.all([fetchAge("age")]).then((data) => {
console.log("DOM before update ="+$('html').html());
data = data[0].replace(/{{age}}/g, year);
$('.mybenifits .content').html(data);
console.log("DOM after update ="+$('html').html());//Able to see the updated DOM
console.log("$('.mybenifits .content').html="+global.$('.mybenifits .content').html());
}).catch((error) => {
console.log(" ******* Error while fetching age info");
});
}
规格代码片段:helper.test.js
const expect = require('chai').expect;
const assert = require('chai').assert;
const sinon = require('sinon');
const { JSDOM } = require('jsdom');
const { updateContent } = require('../../main/webpack/common/helper.js');
describe('Helper - Example', () => {
it('should update the content', () => {
let htmlStr = '<!doctype html><html><body><div class="mybenifits"><div class="content"></div></div></body></html>';
const jsdom = new JSDOM(htmlStr, {
url: 'http://localhost/',
});
//Setting Global variables - start
global.window = jsdom.window;
global.document = jsdom.window.document;
global.$ = require('jquery');
//Setting GLobal variables - end
//Mocking fetchAge function
function fetchAge(featurename) {
return '<p id="fcontent">Current Age is {{age}}</p>';
}
updateContent("2020",fetchAge);
console.log("Total html file ="+$('html').html());
//expect($('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
//expect(global.$('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');//Not working even if I use global
});
});
您的错误可能是因为您的 updateContent
函数在其余代码继续执行的同时异步执行其操作。这可能意味着 expect
断言在 在 updateContent
完成规范更新之前被调用。
首先,我怎么强调都不为过 - 充分了解 Promises
及其工作原理以及 async/await
关键字将非常有用(并且可能必不可少的)在长 运行.
这是未测试的,但应该会让您走上正确的道路。我假设您的 fetchAge()
函数正在返回一个 Promise - 即调用 API 来检索年龄 - 或类似的?
// Since you're only resolving one promise, you don't need `Promise.all`. `fetchAge` returns a promise and so you can chain `then` directly onto it.
// Also, we can `return` the promise here in case you want to do `updateContent().then(...)` later
function updateContent(year, fetchAge) {
return fetchAge("age")
.then((data) => {
// ...
data = data[0].replace(/{{age}}/g, year);
$('.mybenifits .content').html(data);
// ...
})
.catch(/* ... */);
}
进行上述更改应该允许您像这样进行测试
此外,由于我们正在使用 then
链测试异步代码,因此您需要确保使用 done
参数,以便我们可以在测试完成时告诉 jest 运行ning .参见 https://jestjs.io/docs/en/asynchronous
it('should update the content', (done) => {
// ...
// Since you're mocking a function that returns a promise, your mock function needs to aswell
function fetchAge(featurename) {
return Promise.resolve('<p id="fcontent">Current Age is {{age}}</p>');
}
updateContent("2020", fetchAge)
.then(() => {
console.log("Total html file ="+$('html').html());
expect($('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
expect(global.$('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
done();
})
.catch(error => done(e));
});
编辑:
仅供参考,这是关于如何使用 async/await
(使用内联类型)重写 updateContent
函数的建议。同样,未在本地测试,因此可能需要进行一两次调整 :)
// Note the `async` keyword
async function updateContent(year: string, fetchAge: () => Promise<string>): Promise<void> {
// Using async/await, we can now use `try/catch` blocks
// instead of `<Promise>.catch()`!
try {
// Note `await`. Since `fetchAge` returns a Promise, we can `await` it!
const data = await fetchAge("age");
const htmlData = data[0].replace(/{{age}}/g, year);
$('.mybenifits .content').html(htmlData);
} catch (error) {
// Add your error handling / logging here
console.error(error);
}
}
然后在您的测试中,您可以简单地等待 updateContent
完成,然后再断言 DOM 值匹配!
it('should update the content', async () => {
// ...
await updateContent("2020", fetchAge);
expect($('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
expect(global.$('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
// ...
});
我正在使用 Mocha/JSDOM 编写功能规范并使用 'chai' 断言。
用例是当我调用函数时:updateContent,
- 它会在内部调用另一个函数来获取一些 HTML 内容。
- 稍后我会处理 HTML 内容并将其添加到现有的 DOM 元素中。
当我在服务器上 运行 时,这工作正常,但问题是当我尝试编写规范时,无法看到更新的 DOM。我通过放置控制台语句检查了 updateContent 函数,我看到了更新的内容,但是一旦控制转移到 spec 函数,我看到原始的 DOM 添加到 JSDOM.
这是使用 Typescript、js 组合编写的,JQuery 用于 DOM 操作
你能帮我解决一下我在这里遗漏了什么吗?任何 suggestion/info 都会有所帮助。 我在访问
时尝试使用全局updateContent 函数在 helper.js 文件
中可用function updateContent(year, fetchAge) {
Promise.all([fetchAge("age")]).then((data) => {
console.log("DOM before update ="+$('html').html());
data = data[0].replace(/{{age}}/g, year);
$('.mybenifits .content').html(data);
console.log("DOM after update ="+$('html').html());//Able to see the updated DOM
console.log("$('.mybenifits .content').html="+global.$('.mybenifits .content').html());
}).catch((error) => {
console.log(" ******* Error while fetching age info");
});
}
规格代码片段:helper.test.js
const expect = require('chai').expect;
const assert = require('chai').assert;
const sinon = require('sinon');
const { JSDOM } = require('jsdom');
const { updateContent } = require('../../main/webpack/common/helper.js');
describe('Helper - Example', () => {
it('should update the content', () => {
let htmlStr = '<!doctype html><html><body><div class="mybenifits"><div class="content"></div></div></body></html>';
const jsdom = new JSDOM(htmlStr, {
url: 'http://localhost/',
});
//Setting Global variables - start
global.window = jsdom.window;
global.document = jsdom.window.document;
global.$ = require('jquery');
//Setting GLobal variables - end
//Mocking fetchAge function
function fetchAge(featurename) {
return '<p id="fcontent">Current Age is {{age}}</p>';
}
updateContent("2020",fetchAge);
console.log("Total html file ="+$('html').html());
//expect($('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
//expect(global.$('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');//Not working even if I use global
});
});
您的错误可能是因为您的 updateContent
函数在其余代码继续执行的同时异步执行其操作。这可能意味着 expect
断言在 在 updateContent
完成规范更新之前被调用。
首先,我怎么强调都不为过 - 充分了解 Promises
及其工作原理以及 async/await
关键字将非常有用(并且可能必不可少的)在长 运行.
这是未测试的,但应该会让您走上正确的道路。我假设您的 fetchAge()
函数正在返回一个 Promise - 即调用 API 来检索年龄 - 或类似的?
// Since you're only resolving one promise, you don't need `Promise.all`. `fetchAge` returns a promise and so you can chain `then` directly onto it.
// Also, we can `return` the promise here in case you want to do `updateContent().then(...)` later
function updateContent(year, fetchAge) {
return fetchAge("age")
.then((data) => {
// ...
data = data[0].replace(/{{age}}/g, year);
$('.mybenifits .content').html(data);
// ...
})
.catch(/* ... */);
}
进行上述更改应该允许您像这样进行测试
此外,由于我们正在使用 then
链测试异步代码,因此您需要确保使用 done
参数,以便我们可以在测试完成时告诉 jest 运行ning .参见 https://jestjs.io/docs/en/asynchronous
it('should update the content', (done) => {
// ...
// Since you're mocking a function that returns a promise, your mock function needs to aswell
function fetchAge(featurename) {
return Promise.resolve('<p id="fcontent">Current Age is {{age}}</p>');
}
updateContent("2020", fetchAge)
.then(() => {
console.log("Total html file ="+$('html').html());
expect($('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
expect(global.$('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
done();
})
.catch(error => done(e));
});
编辑:
仅供参考,这是关于如何使用 async/await
(使用内联类型)重写 updateContent
函数的建议。同样,未在本地测试,因此可能需要进行一两次调整 :)
// Note the `async` keyword
async function updateContent(year: string, fetchAge: () => Promise<string>): Promise<void> {
// Using async/await, we can now use `try/catch` blocks
// instead of `<Promise>.catch()`!
try {
// Note `await`. Since `fetchAge` returns a Promise, we can `await` it!
const data = await fetchAge("age");
const htmlData = data[0].replace(/{{age}}/g, year);
$('.mybenifits .content').html(htmlData);
} catch (error) {
// Add your error handling / logging here
console.error(error);
}
}
然后在您的测试中,您可以简单地等待 updateContent
完成,然后再断言 DOM 值匹配!
it('should update the content', async () => {
// ...
await updateContent("2020", fetchAge);
expect($('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
expect(global.$('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');
// ...
});