programing

Jest expect에 맞춤형 메시지를 추가하는 방법은?

itmemos 2023. 10. 4. 21:00
반응형

Jest expect에 맞춤형 메시지를 추가하는 방법은?

이미지 다음 테스트 사례:

it('valid emails checks', () => {
  ['abc@y.com', 'a@b.nz'/*, ...*/].map(mail => {
    expect(isValid(mail)).toBe(true);
  });
});

각 이메일마다 다음과 같이 자동 생성된 메시지를 추가하고 싶습니다.Email 'f@f.com' should be valid실패한 테스트 사례를 쉽게 찾을 수 있도록 합니다.

다음과 같은 경우:

// .map(email =>
expect(isValid(email), `Email ${email} should be valid`).toBe(true);

농담으로 가능한가요?

차이에서는 다음과 같은 두 번째 매개 변수를 사용할 수 있었습니다.expect(value, 'custom fail message').to.be...그리고 재스민은 이제 끝인 것 같습니다..because하지만 제스트에서 해결책을 찾을 수 없습니다.

jest: https://github.com/mattphillips/jest-expect-message 을 확장하는 lib을 사용해 보십시오.

test('returns 2 when adding 1 and 1', () => {
  expect(1 + 1, 'Woah this should be 2!').toBe(3);
});

그런 메시지를 제공하는 것은 불가능할 것 같습니다.하지만 당신은 당신 자신의 짝을 정의할 수 있습니다.

예를 들어, 당신은 a를 만들 수 있습니다.toBeValid(validator)일치하는 항목:

expect.extend({
  toBeValid(received, validator) {
    if (validator(received)) {
      return {
        message: () => `Email ${received} should NOT be valid`,
        pass: true
      };
    } else {
      return {
        message: () => `Email ${received} should be valid`,
        pass: false
      };
    }
  }
});

그리고는 이렇게 사용합니다.

expect(mail).toBeValid(isValid);

참고:toBeValid를 사용할 수 있으므로 두 경우(성공 및 실패)에 대한 메시지를 반환합니다.테스트는 유효성 검사를 통과할지 여부에 따라 해당 메시지와 함께 실패합니다.

expect(mail).toBeValid(isValid);
// pass === true: Test passes
// pass === false: Failure: Email ... should be valid

expect(mail).not.toBeValid(isValid);
// pass === true: Failure: Email ... should NOT be valid
// pass === false: Test passes

일반적인 솔루션은 아니지만 루프에서 항목을 구별하기 위한 사용자 지정 예외 메시지를 원하는 일반적인 경우 Jest의 test.each를 사용할 수 있습니다.

예를 들어, 샘플 코드:

it('valid emails checks', () => {
  ['abc@y.com', 'a@b.nz'/*, ...*/].map(mail => {
    expect(isValid(mail)).toBe(true);
  });
});

대신에 될 수도 있습니다.

test.each(['abc@y.com', 'a@b.nz'/*, ...*/])(
    'checks that email %s is valid',
    mail => {
        expect(isValid(mail)).toBe(true);
    }
);

이것을 내가 쓰고 있는 어떤 코드에서 내 것을.it안에 있는 블록들forEach.

이렇게 함으로써 저는 여러분이 설명하고 있는 내용에 대해 매우 정확한 근사치를 얻을 수 있었습니다.

장점:

  • 우수한 "원본" 오류 보고서
  • 주장을 자체 검정으로 계산합니다.
  • 플러그인이 필요 없습니다.

제 방법으로 코드를 사용하는 방법은 다음과 같습니다.


// you can't nest "it" blocks within each other,
// so this needs to be inside a describe block. 
describe('valid emails checks', () => {
  ['abc@y.com', 'a@b.nz'/*, ...*/].forEach(mail => {
    // here is where the magic happens
    it(`accepts ${mail} as a valid email`, () => {
      expect(isValid(mail)).toBe(true);
    })
  });
});

그러면 오류가 이렇게 나타납니다.

이것들이 얼마나 멋진지 주목하세요!

 FAIL  path/to/your.test.js
  ● valid emails checks › accepts abc@y.com as a valid email

    expect(received).toBe(expected)

    Expected: "abc@y.com"
    Received: "xyz@y.com"

      19 |    // here is where the magic happens
      20 |    it(`accepts ${mail} as a valid email`, () => {
    > 21 |      expect(isValid(mail)).toBe(true);
                                       ^
      22 |    })

트라이캐치를 사용할 수 있습니다.

try {
    expect(methodThatReturnsBoolean(inputValue)).toBeTruthy();
}
catch (e) {
    throw new Error(`Something went wrong with value ${JSON.stringify(inputValue)}`, e);
}

사용자 지정 오류 메시지를 추가하는 또 다른 방법은fail()방법:

it('valid emails checks', (done) => {
  ['abc@y.com', 'a@b.nz'/*, ...*/].map(mail => {
    if (!isValid(mail)) {
      done.fail(`Email '${mail}' should be valid`)
    } else {
      done()
    }
  })
})

저는 이 문제를 직접 해결해야 했습니다. 저는 이 문제에 대해 PR을 할 수 있을 것 같습니다. 하지만 이 문제는 여러분이 원하는 대로 사용할 수 있습니다.기본적으로 curryed 함수가 세 번째 매개 변수로 사용자 지정 메시지를 가질 수 있도록 하는 사용자 지정 방법을 만듭니다.

기대가 첫 번째 매개 변수(에 들어가는 매개 변수)를 설정한다는 것을 기억하는 것이 중요합니다.expect(akaThisThing)사용자 정의 함수의 첫 번째 매개 변수로 사용됩니다.

일반적인 Jest Message Extender의 경우 이미 사용할 수 있는 Jest Message가 있으면 다음과 같은 기능을 추가할 수 있습니다.

expect.extend({
  toEqualMessage(received, expected, custom) {
    let pass = true;
    let message = '';
    try {
      // use the method from Jest that you want to extend
      // in a try block
      expect(received).toEqual(expected);
    } catch (e) {
      pass = false;
      message = `${e}\nCustom Message: ${custom}`;
    }
    return {
      pass,
      message: () => message,
      expected,
      received
    };
  }
});

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace jest {
    // eslint-disable-next-line @typescript-eslint/naming-convention
    interface Matchers<R> {
      toEqualMessage(a: unknown, b: string): R;
    }
  }
}

다음과 같이 나타납니다.

    Error: expect(received).toEqual(expected) // deep equality

    Expected: 26
    Received: 13
    Custom Message: Sad Message Indicating failure :(

사용 사례에 도움이 되는 경우의 기대(actualObject.toBe()) 내부를 구체적으로 살펴보면 다음과 같습니다.

import diff from 'jest-diff'

expect.extend({
toBeMessage (received, expected, msg) {
  const pass = expected === received
  const message = pass
? () => `${this.utils.matcherHint('.not.toBe')}\n\n` +
        `Expected value to not be (using ===):\n` +
        `  ${this.utils.printExpected(expected)}\n` +
        `Received:\n` +
        `  ${this.utils.printReceived(received)}`
      : () => {
        const diffString = diff(expected, received, {
          expand: this.expand
        })
        return `${this.utils.matcherHint('.toBe')}\n\n` +
        `Expected value to be (using ===):\n` +
        `  ${this.utils.printExpected(expected)}\n` +
        `Received:\n` +
        `  ${this.utils.printReceived(received)}` +
        `${(diffString ? `\n\nDifference:\n\n${diffString}` : '')}\n` +
        `${(msg ? `Custom:\n  ${msg}` : '')}`
      }

    return { actual: received, message, pass }
  }
})

// usage:
expect(myThing).toBeMessage(expectedArray, ' was not actually the expected array :(')

다음을 사용할 수 있습니다. (테스트 내에서 정의할 수 있습니다.)

      expect.extend({
ToBeMatch(expect, toBe, Msg) {  //Msg is the message you pass as parameter
    const pass = expect === toBe;
    if(pass){//pass = true its ok
        return {
            pass: pass,
            message: () => 'No ERRORS ',
          };
    }else{//not pass
        return {
            pass: pass,
            message: () => 'Error in Field   '+Msg + '  expect  ' +  '  ('+expect+') ' + 'recived '+'('+toBe+')',
          };
    }
},  });

이렇게 쓰시면 됩니다.

     let z = 'TheMassageYouWantWhenErrror';
    expect(first.name).ToBeMatch(second.name,z);

.fail()줄 템플릿으로

예.

it('key should not be found in object', () => {
    for (const key in object) {
      if (Object.prototype.hasOwnProperty.call(object, key)) {
        const element = object[key];
        if (element["someKeyName"] === false) {
          if (someCheckerSet.includes(key) === false) {
            fail(`${key} was not found in someCheckerSet.`)
          }
        }

@Zargold의 답변을 자세히 소개하자면:

다음과 같은 더 많은 옵션이 필요합니다.comment아래, MatcherHintOptions 문서 참조

// custom matcher - omit expected
expect.extend({
  toBeAccessible(received) {
    if (pass) return { pass };
    return {
      pass,
      message: () =>
        `${this.utils.matcherHint('toBeAccessible', 'received', '', {
          comment: 'visible to screen readers',
        })}\n
Expected: ${this.utils.printExpected(true)}
Received: ${this.utils.printReceived(false)}`,
    };
  }

enter image description here

// custom matcher - include expected
expect.extend({
  toBeAccessible(received) {
    if (pass) return { pass };
    return {
      pass,
      message: () =>
        `${this.utils.matcherHint('toBeAccessible', 'received', 'expected', { // <--
          comment: 'visible to screen readers',
        })}\n
Expected: ${this.utils.printExpected(true)}
Received: ${this.utils.printReceived(false)}`,
    };
  }

enter image description here

값을 사용하는 대신 설명 레이블이 있는 튜플을 전달합니다.예를 들어 양식 유효성 검사 상태를 주장할 때 유효하지 않은 것으로 표시할 레이블을 다음과 같이 반복합니다.

errorFields.forEach((label) => {
  const field = getByLabelText(label);

  expect(field.getAttribute('aria-invalid')).toStrictEqual('true');
});

그러면 다음 오류 메시지가 나타납니다.

expect(received).toStrictEqual(expected) // deep equality

    - Expected  - 1
    + Received  + 1

      Array [
        "Day",
    -   "false",
    +   "true",
      ]

를 .expect할 것을 toThrow()아니면not.toThrow()그런 . .jest출력에 사용자 지정 텍스트를 포함합니다.

// Closure which returns function which may throw
function isValid (email) {
  return () => {
     // replace with a real test!
     if (email !== 'some@example.com') {
       throw new Error(`Email ${email} not valid`)
     }
  }
}

expect(isValid(email)).not.toThrow()

저는 평소에 이런 걸 쓰고 있어요.

it('all numbers should be in the 0-60 or 180-360 range', async () => {
    const numbers = [0, 30, 180, 120];
    for (const number of numbers) {
        if ((number >= 0 && number <= 60) || (number >= 180 && number <= 360)) {
            console.log('All good');
        } else {
            expect(number).toBe('number between 0-60 or 180-360');
        }
    }
});

생성:

@Monarch Wadia answer를 따라 데이터 객체와 테스트가 포함된 콜백을 취한 후 각 객체 항목에 대해 이 콜백을 반복하는 기능을 만들었습니다.

function testDataSet(title, obj, func) {
  describe(title, () => {
    for (const k in obj) {
      test(`With data set: ${k}`, () => {
        func(obj[k]);
      });
    }
  });
}

사용.

testDataSet('My test case', { a: 'a1', b: 'b1' }, (data) => {
  expect(data).toEqual('a1');
});

결과.

 FAIL  file.test.js
  My test case
    √ With data set: a (8 ms)
    × With data set: b (9 ms)

  ● My test case › With data set: b

    expect(received).toEqual(expected) // deep equality

    Expected: "a1"
    Received: "b1"

      102 |
      103 | testDataSet('My test case', { a: 'a1', b: 'b1' }, (data) => {
    > 104 |   expect(data).toEqual('a1');
          |                ^
      105 | });
      106 |

언급URL : https://stackoverflow.com/questions/45348083/how-to-add-custom-message-to-jest-expect

반응형