Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: 테스트 리팩토링 #102

Merged
merged 3 commits into from
Jul 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 15 additions & 33 deletions packages/sdk-loader/src/loadScript.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,31 @@ describe('loadScript', () => {
delete window.TossPayments;

document.head.innerHTML = '';
document.head.appendChild = vi.fn(); // NOTE: 테스트 환경에서 script inject 방지
});

describe('기본 동작', () => {
test('script 로드가 완료되면, 주어진 namespace에 생성된 인스턴스와 동일한 인스턴스를 resolve 해야한다', async () => {
// given
const { loadScript } = await import('./loadScript');

const { script, eventListeners } = mockScriptElement();

vi.spyOn(document, 'createElement')
.mockReturnValueOnce(script)
const { script } = mockScriptElement();

// when
const promise = loadScript('http://example.com/example.js', 'TossPayments');
window.TossPayments = vi.fn(); // SDK는 주어진 namespace에 인스턴스를 생성함
eventListeners.load(new Event('load')); // script 로드가 완료됨
script.dispatchEvent(new Event('load')); // script 로드가 완료됨

// then
expect(promise).resolves.toBe(window.TossPayments);
});
test('script 로드를 실패하면, cachedPromise가 null로 설정되고 에러를 throw 해야한다', async () => {
// given
const { loadScript } = await import('./loadScript');
const { script, eventListeners } = mockScriptElement();

vi.spyOn(document, 'createElement')
.mockReturnValueOnce(script)
const { script } = mockScriptElement();

// when
const promise = loadScript('http://example.com/example.js', 'TossPayments');
eventListeners.error(new Event('error')); // script 로드가 실패함
script.dispatchEvent(new Event('error')); // script 로드가 실패함

// then
await expect(promise).rejects.toThrowError('[TossPayments SDK] Failed to load script: [http://example.com/example.js]');
Expand All @@ -57,31 +50,24 @@ describe('loadScript', () => {
test('script 로드를 성공했지만 namespace에 인스턴스가 존재하지 않으면, 에러를 throw 해야한다', async () => {
// given
const { loadScript } = await import('./loadScript');
const { script, eventListeners } = mockScriptElement();

vi.spyOn(document, 'createElement')
.mockReturnValueOnce(script)
const { script } = mockScriptElement();

// when
const promise = loadScript('http://example.com/example.js', 'TossPayments');
eventListeners.load(new Event('load')); // script 로드가 완료됨
script.dispatchEvent(new Event('load')); // script 로드가 완료됨

// then
expect(promise).rejects.toThrowError('[TossPayments SDK] TossPayments is not available');
});
test('priority 옵션을 설정하면, script element의 fetchPriority 속성이 설정되어야 한다', async () => {
// given
const { loadScript } = await import('./loadScript');
const { script, eventListeners } = mockScriptElement();

vi.spyOn(document, 'createElement')
.mockReturnValueOnce(script)

const { script } = mockScriptElement();

// when
const promise = loadScript('http://example.com/example.js', 'TossPayments', { priority: 'high' });
window.TossPayments = vi.fn(); // SDK는 주어진 namespace에 인스턴스를 생성함
eventListeners.load(new Event('load')); // script 로드가 완료됨
script.dispatchEvent(new Event('load')); // script 로드가 완료됨

// then
expect((script as any).fetchPriority).toBe('high');
Expand All @@ -94,15 +80,12 @@ describe('loadScript', () => {
// given
const { loadScript } = await import('./loadScript');

const { script, eventListeners } = mockScriptElement();

vi.spyOn(document, 'createElement')
.mockReturnValueOnce(script)
const { script } = mockScriptElement();

// when
const promise1 = loadScript('http://example.com/script.js', 'TossPayments');
window.TossPayments = vi.fn(); // SDK는 주어진 namespace에 인스턴스를 생성함
eventListeners.load(new Event('load')); // script 로드가 완료됨
script.dispatchEvent(new Event('load')); // script 로드가 완료됨

const promise2 = loadScript('http://example.com/script.js', 'TossPayments');

Expand Down Expand Up @@ -146,13 +129,12 @@ describe('loadScript', () => {
});

function mockScriptElement() {
// NOTE: script의 load, error 이벤트를 임의로 발생시키기 위해 이벤트 리스너를 mocking 합니다
const eventListeners = {} as { [key: string]: EventListener };
document.head.appendChild = vi.fn(); // NOTE: 테스트 환경에서 script inject 방지

const script = document.createElement('script');

script.addEventListener = (event: string, listener: EventListener) => {
eventListeners[event] = listener;
};
vi.spyOn(document, 'createElement')
.mockReturnValueOnce(script);

return { script, eventListeners };
return { script };
}
Loading