typescript 如何让Jasmine测试忽略多行字符串中的制表符

mw3dktmi  于 2023-05-19  发布在  TypeScript
关注(0)|答案(2)|浏览(134)

我有一个函数,它返回一个多行字符串,如下所示:

example line 1
example line 2
example line 3

我希望能这样写:

it('should get the proper data', () => {
  expect(service.getData('foo').toEqual(
  `example line 1
    example line 2
    example line 3`);
});

但这当然会给予我这个错误,因为测试在大多数行之前添加了一些空格:

Expected 'example line 1
example line 2
example line 3' to equal 'example line 1
    example line 2
    example line 3'.

现在,我显然知道我可以通过添加\n字符或手动删除空格来稍微不同地编写测试,但这在我的测试中看起来有点丑陋。
我希望有一种实用程序可以像这样使用:

it('should get the proper data', () => {
  expect(service.getData('foo').toEqual(
  util.safeUnindent(`example line 1
    example line 2
    example line 3`));
});

有没有什么插件可以安全可靠地去掉这样的缩进,我只需要自己滚动,还是应该使用\n字符?

3htmauhk

3htmauhk1#

看起来你必须自己滚动一点(我还没有找到任何开箱即用的解决方案)。
但是我很快想到了一些事情,我发现定制匹配器是最优雅的。
1.使用toContain检查返回的字符串中是否包含预期内容
1.使用toMatch-使用正则表达式(RegEx)进行检查
1.使用自定义匹配器-非常可重用且易于阅读
参见https://jasmine.github.io/api/edge/matchershttps://jasmine.github.io/tutorials/custom_matcherhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions
要测试的功能:

function getData(x){
    return `
    example line 1
    example line 2
    example line 3
    `
}

测试设置:

function trimmedLines(untrimmed){
    // trim leading and trailing spaces and newlines and split at inner newlines
    const lines = untrimmed.trim().replace(/^\n+/, '').replace(/\n+$/, '').split('\n')
    const trimmedLines = []
    lines.forEach(line => {
        // trim and add each line to new array
        trimmedLines.push(line.trim())
    });
    // return a trimmed string
    return trimmedLines.join('\n')
}

const customMatchers = {
    ToEqualTrimmed: function(matchersUtil) {
        return {
            compare: function(actual, expected) {
                if (expected === undefined) expected = '';
                const result = { };
                result.pass = matchersUtil.equals(
                    trimmedLines(actual),
                    trimmedLines(expected)
                )

                if (result.pass) {
                    result.message = "Expected " + actual + " to be trimmed equal to" + expected;
                } else {
                    result.message = "Expected " + actual + " to be trimmed equal to" + expected + ' But was not!';
                }
                return result;
            }
        };
    }
};

beforeEach(function() {
    jasmine.addMatchers(customMatchers);
});

describe("Outer test desc", () => {
    it('should get the proper data', () => {
        const output = getData('foo')
        // this fails
        expect(output).toEqual(
          `example line 1
            example line 2
            example line 3`);
        // these 3 pass
        expect(output).toContain('example line 1')
        expect(output).toContain('example line 2')
        expect(output).toContain('example line 3')
        // this passes too
        expect(output).toMatch('[ \n]*example line 1[ \n]*example line 2[ \n]*example line 3[ \n]*');
        // passes too
        expect(output).ToEqualTrimmed(
          `example line 1
            example line 2
            example line 3`);

    });

});

[ \n]*匹配零个或多个空格或换行符。

gj3fmq9x

gj3fmq9x2#

我回想起我参与的一个老项目,TSLint。我记得他们的测试有一个dedent方法,用于测试TypeScript代码的字符串作为其linter的输入/输出。我找到了他们的dedent方法源代码,下面是一个使用它的JSON代码字符串的示例
所以我修改了一下,真的简化了,变成了这个,看起来对我有用。

export function dedent(inputStrings: TemplateStringsArray, ...values: any[]) {
  //Convert template string arr into a real string
  const fullString = inputStrings.reduce(
    (accumulator, str, i) => `${accumulator}${values[i - 1]}${str}`
  );

  //on each line, remove any leading whitespace
  return fullString
    .split('\n')
    .map((line) => line.replace(/^[\t\s]*/, ''))
    .join('\n');
}

我可以像这样使用它,这很酷,因为它像函数一样工作,但我不需要左括号或右括号

import { dedent } from 'test-utils';

it('should get the proper data', () => {
  expect(service.getData('foo'))
    .toEqual(dedent`example line 1
                    example line 2
                    example line 3`);
});

现在在我的项目的早期阶段,这似乎对我现有的测试工作得很好。这看起来像是一个很好的方式来推进这一点,或者我错过了什么,可能会咬我在未来?

相关问题