Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.9k views
in Technique[技术] by (71.8m points)

jest mock oauth popup window in reactjs typescript

I have started to learn unit testing my React Apps using Jest + React Testing Library.

I have a project into which I am adding tests. I have button which performs GitHub OAuth by bringing up a popup window on button click. Code for my popup window logic which I have in a class GitHubOAuth.ts which is as follows:-

    class GitHubOAuth {
        private id: any;
        popupPromise: any;
        popupWindow: any;
        popupTimer: any;
    
        constructor(id: any) {
            this.id = id
        }
    
        checkPopup() {
            this.popupPromise = new Promise((resolve, reject) => {
                this.popupTimer = window.setInterval(() => {
                    try {
                        const popupWindow = this.popupWindow
    
                        if (!popupWindow || popupWindow.closed || popupWindow.closed === undefined) {
                            this.closePopup()
                            reject("Popup was closed")
    
                            return
                        }
    
                        if (popupWindow.location.pathname === "blank")
                            return
    
                        const code = popupWindow.location.href.match(/\?code=(.*)/) &&
                            popupWindow.location.href.match(/\?code=(.*)/)[1]
    
                        resolve({ code, success: true })
    
                        this.closePopup()
                    } catch (err) {
                        console.log("Error: ", err)
                    }
                }, 500)
            })
        }
    
        openPopup() {
            const width = 600,
                height = 600
            const left = window.innerWidth / 2 - width / 2
            const top = window.innerHeight / 2 - height / 2
    
            const url =
                "https://github.com/login/oauth/authorize?scope=read:user,user:email&client_id=69c3fc731ccb2d116412&redirect_uri=http://localhost:3000"
    
            this.popupWindow = window.open(
                url,
                "",
                `toolbar=no, location=no, directories=no, status=no, menubar=no, 
                scrollbars=no, resizable=no, copyhistory=no, width=${width}, 
                height=${height}, top=${top}, left=${left}`
            )
        }
    
        closePopup() {
            this.cancelGitHubOAuth()
            this.popupWindow.close()
        }
    
        cancelGitHubOAuth() {
            if (this.popupTimer) {
                window.clearInterval(this.popupTimer)
                this.popupTimer = null
            }
        }
    
        then(...args: any[]) {
            return this.popupPromise.then(...args)
        }
    
        catch(...args: any[]) {
            return this.popupPromise.then(...args)
        }
    
        static startGitHubOAuth(id: string) {
            const popup = new this(id)
    
            popup.openPopup()
            popup.checkPopup()
    
            return popup
        }
    }
    
    export default GitHubOAuth 

And this is how I call it from my App.tsx class:-

    const handleLogin = () => {
        const githubOAuth = GitHubOAuth.startGitHubOAuth("GitHubOAuth")
        githubOAuth
            .then(({ success, code }: { success: boolean, code: string }) => {
                if (success) performGitHubLogin(code)
            })
            .catch((err: any) => console.error(err))
    }

handleLogin is called when a button is clicked. Now I want to write my test around when user clicks on that login button and want to mock the GitHubOAuth class altogether. But I am continuously getting either:- cannot call .then() of undefined or cannot call .startGitHubOAuth of undefined.

I have tried manual mocks of jest but they are not working as expected.

Please help me with the test would be great if you can provide a working solution. My folder structure:-

src/
├── App.css
├── App.test.tsx  // Testing login click from here
├── App.tsx
├── components
│   ├── NavigationBar
│   │   ├── GitHubOAuth.ts
│   │   ├── index.tsx
│   │   ├── __mocks__
│   │   │   └── GitHubOAuth.ts // Implemented mock calls
│   │   └── __tests__
│   │       └── index.test.tsx
├── index.tsx
├── react-app-env.d.ts
├── serviceWorker.ts
└── setupTests.ts

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...