微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

修改后无法在规范中看到更新的 DOM

如何解决修改后无法在规范中看到更新的 DOM

我正在使用 Mocha/JSDOM 编写功能规范并使用“chai”进行断言。

用例是当我调用函数时:updateContent,

  1. 它会在内部调用一个函数获取一些 HTML 内容
  2. 稍后我会处理该 HTML 内容并将其添加到现有的 DOM 元素中。

当我在服务器上运行时,这工作正常,但问题是当我尝试编写规范时,无法看到更新的 DOM。我通过放置控制台语句检查了 updateContent 函数,我看到了更新的内容,但是一旦控制转移到 spec 函数,我就会看到添加到 JSDOM 的原始 DOM。

这是使用Typescript、js组合、JQuery编写的DOM操作

你能帮我解决在这里遗漏的问题吗?任何建议/信息都会有所帮助。 我尝试在访问时使用 global

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。见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));
});

编辑: 仅供参考,这是关于如何使用 updateContent(使用内联类型)重写 async/await 函数的建议。同样,未在本地进行测试,因此可能需要进行一两次调整:)

// 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);
    }
}

然后在您的测试中,您可以在断言 DOM 值匹配之前简单地等待 updateContent 完成!

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>');
    // ...
});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。