Ожидать элемент в массиве

Один из моих тестов ожидает, что текст сообщения об ошибке будет одним из нескольких значений. Поскольку getText() возвращает обещание, я не могу использовать toContain() jasmine matcher. Следующее не будет работать, поскольку protractor (jasminewd under-the-hood) не разрешит обещание во второй части соединителя toContain() в этом случае:

expect(["Unknown Error", "Connection Error"]).toContain(page.errorMessage.getText());

Вопрос: Есть ли способ проверить, находится ли элемент в массиве с жасмином + транспортиром, где элемент является обещанием?

Другими словами, я ищу инверсию toContain(), чтобы expect() неявно разрешал обещанное обещание.


В качестве обходного пути я могу явно решить обещание с помощью then():

page.errorMessage.getText().then(function (text) {
    expect(["Unknown Error", "Connection Error"]).toContain(text);
});

Я не уверен, что это лучший вариант. Я также был бы в порядке с решением, основанным на сторонних моделях, таких как jasmine-matchers.


В качестве примера такой тип утверждения существует в Python:

self.assertIn(1, [1, 2, 3, 4]) 

Ответ 1

Похоже, вам нужен пользовательский соединитель. В зависимости от версии Jasmine вы используете:

С Жасмин 1:

this.addMatchers({
    toBeIn: function(expected) {
        var possibilities = Array.isArray(expected) ? expected : [expected];
        return possibilities.indexOf(this.actual) > -1;
    }
});


С Жасмин 2:

this.addMatchers({
    toBeIn: function(util, customEqualityTesters) {
        return {
            compare: function(actual, expected) {
                var possibilities = Array.isArray(expected) ? expected : [expected];
                var passed = possibilities.indexOf(actual) > -1;

                return {
                    pass: passed,
                    message: 'Expected [' + possibilities.join(', ') + ']' + (passed ? ' not' : '') + ' to contain ' + actual
                };
            }
        };
    }
});


Вам нужно выполнить это в разделе beforeEach для каждого из ваших блоков describe, которые он будет использоваться.

Ваш прогноз будет выглядеть так:

expect(page.errorMessage.getText()).toBeIn(["Unknown Error", "Connection Error"]);

Ответ 2

Альтернативным решением является использование .toMatch() -сервера с Регулярными выражениями и, в частности, специальный символ | (называемый "или" ), который позволяет только совместить одна запись для успеха:

expect(page.errorMessage.getText()).toMatch(/Unknown Error|Connection Error/);

Ответ 3

Для меня наиболее подходящим решением является work-around. Однако мы не должны забывать, что это асинхронное выполнение, и вы можете рассмотреть асинхронную поддержку Jasmine.

Затем ваш тест будет выглядеть следующим образом:

it('should check item is in array', function(done){ //Note the argument for callback

    // do your stuff/prerequisites for the spec here

    page.errorMessage.getText().then(function (text) {
        expect(["Unknown Error", "Connection Error"]).toContain(text);
        done(); // Spec is done! 
    });
});

Примечание. Если вы не передадите этот аргумент done в spec callback, он будет запущен до завершения без сбоев, но никаких утверждений не будет сообщено в ходе выполнения результаты для этой спецификации (другими словами, эта спецификация будет иметь утверждения 0), и это может привести к путанице.