使用静态成员时,如何在Jasmine测试中避免竞争情况?

时间:2018-09-01 13:51:05

标签: javascript typescript jasmine karma-jasmine karma-runner

我有与Karma一起运行的Jasmine测试。这些测试覆盖具有用于控制行为的静态属性的对象。更改这些静态属性会对不希望它们偏离默认值的测试产生不利影响。更具体地说,此测试:

it('honors the base64CharactersPerLine option', () => {
    const testData = new Uint8Array([ 0x01, 0x02, 0x03, 0x04 ]);
    const pem = new PEMObject();
    pem.header = "CERTIFICATE";
    pem.data = testData;
    PEMObject.base64CharactersPerLine = 1; // Causes race condition
    const encodedData = pem.encode();
    console.info(encodedData);
    console.info(encodedData.match(/^\w/g));
    expect(encodedData.match(/^\w$/g).length).toBeGreaterThan(testData.length);
});

对该测试有不利影响:

it('decoding then encoding returns the original data', () => {
    const pem = new PEMObject();
    pem.header = "CERTIFICATE";
    pem.decode(testPEM);
    expect(pem.encode()).toEqual(testPEM);
});

通过在后一个测试中使pem.encode()的输出与原始输入testPEM(a string)不同。

我想知道的更普遍的问题是:如何在使用静态成员修改行为的Karma / Jasmine测试中防止竞争条件?

2 个答案:

答案 0 :(得分:0)

您确定这是一种竞争状况,而不仅仅是您要修改许多测试使用的对象的问题吗?

您也许可以在运行测试之前保存base64CharactersPerLine字段的旧值,然后再恢复它,以便其他测试看到 right 值。

答案 1 :(得分:0)

在测试中为静态值分配新值将影响以后运行的所有其他测试。

有两种方法可以解决此问题。首先,在beforeEach块中,缓存静态属性的原始值,然后在afterEach块中将其重置。像这样:

let cachedValue;
beforeEach(() => cachedValue = PEMObject.base64CharactersPerLine);
afterEach(() => PEMObject.base64CharactersPerLine = cachedValue);

这是可行的,但是维护起来很复杂,并且会因为测试过程中要处理的静态属性而产生原因。

更好的方法是从使用静态属性更改为使用静态方法(尽管这需要更改您的基本代码)。一旦使用静态方法,您就可以使用茉莉花间谍,在每次测试运行后将其清除。因此,您将执行以下操作:

// in your base code
PEMObject.getBase64CharactersPerLine = () => SOME_VALUE;

// in your 'honors the base64CharactersPerLine option' test
spyOn(PEMObject, 'getBase64CharactersPerLine').and.returnValue(1);

您将不再需要beforeEach / afterEach块。