데이터베이스에서 데이터를 가져 오는 데이터 액세스 클래스가 있습니다. 그것은 mixin 즉 ReferenceData로 구현됩니다.이 클래스를 MockReferenceData 클래스로 바꾸려면 단위 테스트에서 DB에 액세스 할 필요가 없습니다. 그러나 작동하지 않습니다.런타임에 Python Mixin 클래스 바꾸기
* 참고 : 종속성 삽입을 사용할 수 없습니다. 팀은 매우 큰 코드 변경이 될 것이라고 생각하면서 사용하지 않으려합니다. 그래서 런타임에 mixin을 대체하려고합니다. 풋 아웃
class MockReferenceData(object):
def dbName(self):
return 'mock'
def totalNumberOfSeats(self):
return '10'
class ReferenceData(object):
def dbName(self):
return 'real DB'
def totalNumberOfSeats(self):
return 'Fetch from DB'
class Car(ReferenceData):
def showNumberOfSeats(self):
print self.totalNumberOfSeats()
class Train(ReferenceData):
def showNumberOfSeats(self):
print self.totalNumberOfSeats()
c = Car()
c.showNumberOfSeats()
t = Train()
t.showNumberOfSeats()
def extend_instance(obj, cls):
"""Apply mixins to a class instance after creation"""
base_cls = obj.__class__
base_cls_name = obj.__class__.__name__
obj.__class__ = type(base_cls_name, (base_cls, cls),{})
extend_instance(c, MockReferenceData)
c.showNumberOfSeats() // output now should be 10
은 다음과 같습니다
Fetch from DB
Fetch from DB
Fetch from DB
내가 할 수있는 새로운 조롱 수준의 출력을 가리 키도록
extend_instance에게 방법을 사용하는 것 같이 내가 기대했다
:
Fetch from DB
Fetch from DB
10
안녕하세요, 문제는 코드 기반이 매우 오래되고 매우 큽니다. 나는 DI를 사용하도록 요청했지만 팀은 그것을 사용하지 않을 것입니다. 그래서 런타임에 mixin을 변경하려고합니다. 가능한가? – Rahul
@ Rahul 본 것처럼, 가능합니다. 나는 여전히 그것을하지 않을 것이다.이와 같이 클래스를 수정하면 모든 종류의 디버깅 문제를 해결할 수 있습니다. 팀이 주장한다면, 그들은 나쁜 일을 주장합니다. 문제를 해결할 수있는 또 다른 옵션은 mixin과 원래 자동차를 상속 한 자동차의 하위 클래스를 만드는 것입니다. 전역 인터프리터 상태를 수정하는 대신 명시적인 클래스를 만들기 때문에보다 안전합니다. – deets
감사합니다. @deets, 나는 그것이 가장 깨끗한 방법이 아니라는 데 동의합니다. 하지만 팀이 원하지 않는다면 나는 선택의 여지가 없습니다. 또한 유닛 테스트에서이 클래스를 확장한다면 설정에서 오브젝트를 만들고 티 아웃에서 파괴 할 때 어떤 영향도 미치지 않을 것이라고 생각합니다. 어떻게 생각해? – Rahul