[Canvas-불꽃놀이-24] SparkParticle 클래스 단위 테스트

이전 글 : [Canvas-불꽃놀이-23] CircleParticle 클래스 단위 테스트

 

[Canvas-불꽃놀이-23] CircleParticle 클래스 단위 테스트

이전 글 : [Canvas-불꽃놀이-22] TextParticle 단위 테스트 [Canvas-불꽃놀이-22] TextParticle 단위 테스트이전 글 : [Canvas-불꽃놀이-21] TailParticle 클래스 단위 테스트 [Canvas-불꽃놀이-21] TailParticle 클래스 단

jinsk-joy.tistory.com

 

SparkParticle 클래스 단위 테스트 진행

 

SparkParticle 단위 테스트

  • Particle의 다른 하위 클래스와 비슷한 방법으로 진행된다.

SparkParticle 클래스 전체 코드

더보기
import Particle from "@/js/particle/Particle.js";
import { SPARK } from "@/js/constants.js";

class SparkParticle extends Particle {
    /**
     * 불꽃 놀이 잔상 효과
     * @param {object} params
     * @param {CanvasRenderingContext2D} params.ctx
     * @param {boolean} params.isSmallScreen
     * @param {number} params.x
     * @param {number} params.y
     * @param {number} params.vx
     * @param {number} params.vy
     * @param {number} params.radius
     * @param {number} params.opacity
     * @param {string} params.color
     */
    constructor({ ctx, isSmallScreen, x, y, vx, vy, radius, opacity, color }) {
        super({ ctx, isSmallScreen, x, y, vx, vy, radius, opacity, color });
    }

    update() {
        this.opacity -= SPARK.OPACITY_ADJUST_RATE;
        this.radius *= SPARK.RADIUS_ADJUST_RATE;

        super.updatePosition();
    }
}

export default SparkParticle;

 

1. 공통 설정

  • 멤버 변수 기본값 계산시 사용되는 메서드를 Mock함수화하고 모든 테스트 전에 Mock함수의 반환값을 설정한다.
  • 생성 시 꼭 필요한 ctx, isSmallScreen은 전역변수로 선언한다. ctx는 매번 테스트할 때마다 새로 생성한다.
// SparkParticle.js
// 기본값 계산에 용되는 메서드 mock 함수화
jest.mock("@/js/utils.js", () => ({
    randomFloat: jest.fn(),
    setRgbaColor: jest.fn(),
}));

describe("SparkParticle 클래스 단위 테스트", () => {
    // 전역변수
    let ctx;
    let isSmallScreen = false;
    const { PARTICLE_DEFAULT_VALUES } = TEST_OPTION;

    // 모든 클래스 실행 전 mock 함수 반환값 지정
    beforeAll(() => {
        randomFloat.mockReturnValue(PARTICLE_DEFAULT_VALUES.opacity);
        setRgbaColor.mockReturnValue(PARTICLE_DEFAULT_VALUES.color);
    });

    // 매번 테스트 실행전 ctx를 새롭게 생성하여 독립적으로 실행할 수 있게 해준다.
    beforeEach(() => {
        ctx = createMockCanvasCtx();
    });
    
    // 테스트 종료 후 등록한 스파이의 호출 기록을 일괄적으로 초기화한다.
    afterEach(() => {
        jest.clearAllMocks();
    });
    
    // 생략...
}

 

2. 생성자와 멤버변수 초기화 테스트

  • 상속받은 부모의 생성자, 멤벼 변수 설정이 오류없이 생성되는지 검증한다. 
// SparkParticle.test.js
test("SpartParticle 생성자와 멤버변수 초기화 테스트", () => {
    const params = { x: 1, y: 1, vx: 20, vy: 20, radius: 10, opacity: 0.45, color: "hsla(270, 60%, 70%)" };
    const spark = new SparkParticle({ ctx, isSmallScreen, ...params });

    expectAllParticleVars(spark, { ...PARTICLE_DEFAULT_VALUES, ...params });
});

 

3. draw 테스트

  • Spark도 별도의 draw 로직 없이 부모의 메서드를 그대로 사용하므로 호출 여부만 확인하도록 한다.
// SparkParticle.test.js
test("SparkParticle draw 테스트", () => {
    const spark = new SparkParticle({ ctx, isSmallScreen, x: 10, y: 10, vx: -1.25, vy: 1.25 });
    
    // 부모의 draw 메서드 호출을 감시하기 위해 jest spy 추가
    const spyParticleDraw = jest.spyOn(Particle.prototype, "draw");
    
    spark.draw();

    // 부모의 draw 메서드 호출되었는지 확인
    expect(spyParticleDraw).toHaveBeenCalled();
});

 

4. update 테스트

  • 부모의 메서드와 Spark만의 별도 로직이 있으므로 업데이트 후 멤버변수의 변화를 검증한다.
// SparkParticle.test.js
test("SparkParticle update 테스트", () => {
    const [x, y, vx, vy, radius, opacity] = [20, 20, 10, 10, 5, 1];
    const spark = new SparkParticle({ ctx, isSmallScreen, x, y, vx, vy, radius, opacity });
    
    // 부모의 메서드 호출을 감시하기위해 jest spy 추가
    const spyParticleUpdatePosition = jest.spyOn(Particle.prototype, "updatePosition");
    spark.update();

    // 예상 결과값과 업데이트 값이 일치하는지 검증
    const expectedResult = {
        ...PARTICLE_DEFAULT_VALUES,
        x: x + vx,
        y: y + vy,
        vx,
        vy,
        radius: radius * SPARK.RADIUS_ADJUST_RATE,
        opacity: opacity - SPARK.OPACITY_ADJUST_RATE,
    };
    expectAllParticleVars(spark, expectedResult);

    // 부모의 메서드가 호출되었는지 확인
    expect(spyParticleUpdatePosition).toHaveBeenCalled();
});

 

5. reset 테스트

  • reset 테스트도 다른 클래스와 마찬가지로 사용 후 풀에 반환하기 위한 초기화와 풀에서 가져온 후 사용하기 위한 초기화로 케이스로 나누어 테스트 한다.

  • 사용후 풀에 반환하기위해 기본값으로 초기화
// SparkParticle.test.js
test("SparkParticle reset 테스트 - 사용된 파티클 풀에 반환시 초기화", () => {
    // 풀에 반납을 위한 reset
    const spark = new SparkParticle({ ctx, isSmallScreen, x: 5, y: 3, vx: 2, vy: -2, radius: 3, opacity: 0.2, color: "rgba(255, 0, 0, 0.8)" });
    
    // 부모의 reset 메서드 호출을 확인하기 위해 jest spy 추가
    const spyParticleReset = jest.spyOn(Particle.prototype, "reset");
    spark.reset();

    // reset후 멤버 변수가 기본값과 일치하는지 검증
    expectAllParticleVars(spark, PARTICLE_DEFAULT_VALUES);
    
    // 부모의 reset 메서드가 호출되었는지 검증
    expect(spyParticleReset).toHaveBeenCalled();
});

  • 기본값으로 초기화된 파티클을 전달된 값으로 재사용하기 위한 초기화 (호출에 대한 검증은 위에서 진행했으므로 생략)
// SparkParticle.test.js
test("SparkParticle reset 테스트 - 풀에서 꺼내와서 재사용", () => {
    const spark = new SparkParticle({ ctx, isSmallScreen });

    // 전달한 params의 값으로 파티클 초기화
    const params = { x: 23, y: 145, vx: 2, vy: 3.35, radius: 2.87, opacity: 0.86 };
    spark.reset(params);

    // reset후 멤버변수의 값이 예상값과 일치하는지 검증
    expectAllParticleVars(spark, { ...PARTICLE_DEFAULT_VALUES, ...params });
});

 

테스트 결과

npx jest ./__test__/particle/SparkParticle.test.js

 

Github Repo
 

GitHub - jinsk9268/text-fireworks

Contribute to jinsk9268/text-fireworks development by creating an account on GitHub.

github.com