темы гуглмок и InSequence - PullRequest
       19

темы гуглмок и InSequence

0 голосов
/ 18 сентября 2018

Рассмотрим сценарий, в котором есть несколько экземпляров класса, есть несколько рабочих потоков для выполнения вещи, каждый поток использует уникальный экземпляр.

Предположим, что многопоточный код выполняет что-то простое, например:

thing->write("discover")
thing->read_until("\n", timeout)
thing->write("version")
thing->read_until("\n", timeout)

Во-первых, я обнаружил, что если я выполню (непоточный) тест (который проверяет вышеупомянутое), тест провалится, например:

EXPECT_CALL(thing, write("discover"));
EXPECT_CALL(thing, read_until("\n", timeout))
    .WillOnce(Return("hello");
EXPECT_CALL(thing, write("version"));
EXPECT_CALL(thing, read_until("\n", timeout));
    .WillOnce(Return("v99");

Если только в началетеста, вы добавляете:

testing::InSequence dummy;

Без этого я обнаружил, что макет использует возвращаемое значение второго вызова «read_until» для каждого вызова read_until, сделанного тестируемым кодом, поэтому я получаю

write: discover
read: v99

Fail.

Хорошо, не проблема, просто добавьте бит InSequence в каждый тест.

Однако, если у меня запущено несколько потоков,вызов InSequence делает невозможным определение того, какие вызовы будут сделаны первыми, поэтому он нарушает тест (очевидно).Но без бита InSequence тест также не пройден, поскольку он всегда использует последнее установленное ожидаемое значение.Что немного раздражает.Я знаю, что вы можете вызывать .WillOnce (Return (val)) много раз при установке ожидания, но есть ли другой способ обойти это?

Я спрашиваю, потому что есть много вызовов (в тестируемом коде) к этому API в разных порядках - каждое ожидание было красиво обернуто в симпатичную вспомогательную функцию, чтобы уменьшить дублирование кода в тестах, например:

void discoverOk(thing)
{
    EXPECT_CALL(thing, write("discover"));
    EXPECT_CALL(thing, read_until("\n", timeout))
        .WillOnce(Return("hello");
}

void discoverError(thing)
{
    // simulate timeout, returns empty string:
    EXPECT_CALL(thing, write("discover"));
    EXPECT_CALL(thing, read_until("\n", timeout))
        .WillOnce(Return("");
}

Очевидно, это не очень хорошо работает с использованием .WillOnce (Return (...)) много раз при установке EXPECT_CALL.

...