如何使用 sinon.js mock/test window.prompt 功能

how to mock/test a window.prompt feature using sinon.js

我有一个 javascript 功能帽子使用提示向用户询问详细信息:

export function askUserForTeamDetails() {
    const emoji = window.prompt( 'Enter new team’s emoji:' );
    if ( null === emoji ) {
        return;
    }
    const name = window.prompt( 'Enter new team’s name:' );
    if ( null === name ) {
        return;
    }
    return { name, emoji };
}

然后我在 HTML 文件中设置了 Qunit 和 Sinon.js,如下所示:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width">
            <title>Rusty Inc. Org Chart WordPress Plugin JavaScript Tests</title>
            <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.7.1.css">
            
        </head>
        <body>
            <div id="qunit"></div>
            <div id="qunit-fixture"></div>
            <div  >
                <h1>Here is the playground</h1>
                <div id="playground"></div>
    
            </div>
           
            <script src="../node_modules/sinon/pkg/sinon.js"></script>
            <script type="module">
                import sinon from "../node_modules/sinon/pkg/sinon-esm.js";
                console.log('is sinon', sinon)
            </script>
              <script src="https://code.jquery.com/qunit/qunit-2.7.1.js"></script>
            <script type="module">
                import { subscribe, updateTree, updateSecretURL, getTree , createExpandCollapseCallback } from '../framework.js';
                import { ui , askUserForTeamDetails } from '../ui.js';
                const q = QUnit;
                
    
                q.test('test details function', assert => {
                let windowSpy = sinon.spy(window, 'prompt');

                //Dont  want  to call the  real function because it will cause propmts to display 

                let  askDetailsSub = sinon.stub(askUserForTeamDetails)
                const fake =  sinon.fake(askUserForTeamDetails);


                 // this gives an error
                sinon.assert.calledOnce(windowSpy); 

                //how to simulate the process of entering  inouts to prompt progamttaically?

                // verify that  the returned values are the ones inout by users


            } )
            </script>
        </body>
    </html>

我觉得我错误地设置了假函数,它给了我一个错误:failing test description message

错误的文字描述是:

Died on test #1     at https://923f663c4822.wp.prod1.devex.live/wp-content/plugins/rusty-inc-org-chart/tests/test.html:68:6: expected prompt to be called once but was called 0 times@ 6 ms
Source:     
AssertError: expected prompt to be called once but was called 0 times
    at Object.fail (https://923f663c4822.wp.prod1.devex.live/wp-content/plugins/rusty-inc-org-chart/node_modules/sinon/pkg/sinon.js:174:25)
    at failAssertion (https://923f663c4822.wp.prod1.devex.live/wp-content/plugins/rusty-inc-org-chart/node_modules/sinon/pkg/sinon.js:120:20)
    at Object.assert.<computed> [as calledOnce] (https://923f663c4822.wp.prod1.devex.live/wp-content/plugins/rusty-inc-org-chart/node_modules/sinon/pkg/sinon.js:149:17)
    at Object.<anonymous> (https://923f663c4822.wp.prod1.devex.live/wp-content/plugins/rusty-inc-org-chart/tests/test.html:76:18)

不应该调用提示吗?

我想测试正在调用的提示,然后模拟向提示输入值。也就是函数 returns 的正确值。我如何测试它?

您不必模拟 askUserForTeamDetails 函数,而是可以存根 window.prompt 函数并通过存根它的 return 值来伪造输入,如下所示:

let windowStub = sinon.stub(window, 'prompt');

//fakes taking input by stubbing the return value of prompt
// use `withArgs` to provide return value for the specific call
windowStub.withArgs('Enter new team’s emoji:').returns(testEmoji);
windowStub.withArgs('Enter new team’s name:').returns(testTeam);

解决方案如下所示:

q.test('tes inputs function', assert => {
                const testEmoji = ``;             
                const testTeam = 'newTeama';
                let windowStub = sinon.stub(window, 'prompt');

                //fakes taking input but stubbing the return value of prompt
                windowStub.withArgs('Enter new team’s emoji:').returns(testEmoji);
                windowStub.withArgs('Enter new team’s name:').returns(testTeam);
                //call the details functions
                const answers = askUserForTeamDetails();
                // restore/free window.prompt from stubbing
                windowSpy.restore();
                //perform the neessary assertions
                assert.ok(  windowStub.withArgs('Enter new team’s emoji:').callCount === 1  , 'Prompt is opened for emoji' );
                assert.ok(  windowStub.withArgs('Enter new team’s name:').callCount === 1  , 'Prompt is opened for  team’s name:' );
                assert.ok( (answers.name === testTeam ) && (answers.emoji === testEmoji)  , 'Returns the values enter in prompt ' );
                

            } )