Как сделать макет Python производным от базового класса?

#python #c #mocking #pybind11

#python #c #насмешливый #пибинд11 #c #издевательство #pybind11

Вопрос:

Я реализую привязки python для некоторого кода на C , используя pybind11. Сейчас я пытаюсь написать модульные тесты для привязок.

class A В C есть такой конструктор, как этот:

 class A
{
    A(std::unique_ptr<B> B_ptr);
}
  

Он принимает a unique_ptr к объекту of class B . class B это абстрактный базовый класс, который может быть производным. Я написал такие привязки, которые class B могут быть получены из Python. Возможно ли, чтобы макет Python, созданный unittest.mock с использованием для получения от class B so, A принимал макет в своем конструкторе?

Ответ №1:

Mocks могут иметь spec определение a, из которого они заимствуют свой сообщаемый класс (наряду со многими другими базовыми поведениями). Итак, самый простой способ сделать это — сделать:

 mymock = Mock(spec=B())  # Mock borrows behaviors of this instance of B, including class
  

Если вы не хотите использовать spec (что имеет много других побочных эффектов), вы можете выполнить целевую модификацию сообщенного класса. у Mock s есть присваиваемый __class__ атрибут, поэтому в противном случае будет пусто Mock , которое сообщает о себе как о подклассе B :

 mymock = Mock()
mymock.__class__ = B
  

Комментарии:

1. На самом деле это не работает, когда этот макет отправляется в функцию C , он отклоняется из-за того, что он не является B или производным от B.

2. @In78: Это меня не совсем удивляет; на уровне расширения C pybind11 может выполняться проверка типов способами, которые обходят Mock псевдокласс в пользу его реального класса. В этом случае, я думаю, вы застряли, вам просто нужно будет переопределить фактический подкласс, B который имеет нужное вам поведение, в котором вы нуждаетесь, извините.

3. Разве в python нет какой-либо макетной структуры, которая позволяет макету быть производным от макетного класса? Например, Google mock работает таким образом для C .