#python #unit-testing #protocol-buffers
#python #модульное тестирование #протокол-буферы
Вопрос:
У меня есть сообщение Google protobuf:
message Foo {
required int bar = 1;
}
Я знаю, что для проверки полей сообщения мы можем использовать:
foo.bar = 1
assert foo.HasField("bar")
Однако «HasField» не работает для повторяющихся типов полей.
Как проверить наличие поля для «повторяющегося типа» полей?
message Foo {
repeated int bar = 1;
}
Комментарии:
1. Похоже, никто действительно не понял ваш вопрос. Вы хотели указать, не было ли предоставлено повторяющееся поле, или если оно было явно установлено пустым. Я пытаюсь добиться того же… вы когда-нибудь находили решение?
Ответ №1:
Вы могли бы попытаться проверить длину повторяющегося поля:
assert len(foo.bar) == 0
Комментарии:
1. но это только дает мне знать, что поле добавлено, но не какое это поле.
2. Да, вы должны знать, какое поле у вас есть в вашем прототипе. Gje
3. Метод hasfield в основном используется для проверки того, установлено ли поле с некоторым значением
4. но hasfield не работает для повторяющихся полей
5. Да, именно поэтому вы можете вместо этого протестировать длину
Ответ №2:
Способ обойти это — включить повторяющееся поле в его собственное сообщение.
message Foo {
message Bars {
repeated int bar = 1;
}
Bars bars = 1;
}
И затем проверьте
foo.bars.SetInParent()
assert foo.HasField("bars")
Таким образом, вы можете определить, не было ли задано повторяющееся поле, потому что не было бы причин добавлять сообщение bars в foo, если не было намерения добавить bar .
Ответ №3:
Учитывая msg
переменную с сообщением, вы можете печатать только повторяющиеся поля, подобные этому. из C # docs
for descr in msg.DESCRIPTOR.fields:
if descr.label == descr.LABEL_REPEATED:
print(f'{descr.name} is repeated')
for i, v_i in enumerate(getattr(msg, descr.name)):
print(f'{i}:{v_i}')
Комментарии:
1. Я точно искал, как проверить, есть ли поле
repeated
. Спасибо!
Ответ №4:
Повторяющиеся поля в файле .proto не поддерживают проверку его существования через has_field_name() .
Следовательно, вы можете проверить размер списка (поскольку повторяющееся поле является списком) и соответствующим образом настроить свою бизнес-логику.
Пример:
рассмотрим ниже файл .proto;
message XYZ {
optional int64 raw_size = 1;
// Repeated messages list
message Abc {
// The line.
optional string line = 2;
}
// List of lines
repeated Abc abc_list = 3;
}
Случай 1:
Проверьте, существует ли ‘raw_size’ в файле .proto.
Решение: XYZ.has_raw_size()
Случай 2: проверьте, существует ли ‘abc_list’ в файле .proto.
Решение: XYZ.abc_list_size()> 0
Ответ №5:
Как уже говорилось в других ответах, это сработает:
assert len(foo.bar) == 0
но если вы не знаете имя поля заранее, скажем, вы пишете утилиту, которая утверждает, что произвольное имя поля в произвольном сообщении содержит хотя бы один элемент, тогда это должно сработать:
assert len(getattr(msg, field_name))
где в вашем случае msg
это «foo» и field_name
«bar».