2014-12-02 80 views
12

我的項目中有兩個不同的模塊。一個是一個配置文件,其中包含如何在Python中修補常量

LOGGING_ACTIVATED = False 

此常數的第二模塊中使用(可以稱之爲主)像下面這樣:

if LOGGING_ACTIVATED: 
    amqp_connector = Connector() 

在我的測試類主要模塊我想修補這個常數與價值

True 

不幸的是,以下不起作用

@patch("config.LOGGING_ACTIVATED", True) 

也不這項工作:

@patch.object("config.LOGGING_ACTIVATED", True) 

有誰知道如何從不同的模塊修補不變?

回答

20

如果if LOGGING_ACTIVATED:測試發生在模塊級別上,則需要確保該模塊尚未先導入。模塊級代碼只運行一次(模塊首次導入到任何地方),則無法測試不會再運行的代碼。

如果測試是在函數中,請注意使用的全局名稱是LOGGING_ACTIVATED,而不是config.LOGGING_ACTIVATED。因此,你需要在這裏打補丁出來main.LOGGING_ACTIVATED

@patch("main.LOGGING_ACTIVATED", True) 

因爲這是你要更換實際參考。

另請參閱mock文檔的Where to patch section

您應該考慮將模塊級代碼重構爲更可測試的代碼。雖然您可以通過從sys.modules映射中刪除模塊對象來強制重新加載模塊代碼,但將純代碼移動到函數中更簡單。

所以,如果你的代碼現在看起來是這樣的:

if LOGGING_ACTIVATED: 
    amqp_connector = Connector() 

考慮使用一個函數:

def main(): 
    global amqp_connector 
    if LOGGING_ACTIVATED: 
     amqp_connector = Connector() 

main() 

或產生甚至屬性的對象。

+0

讓我失望吧,我正在忙着試圖弄清楚'patch()'是否能夠修補'__main__'模塊,以防萬一這就是「call it main」的意思。 – 2014-12-02 15:28:11

+0

@SteveJessop:備案:是的。就Python而言,'__main__'只是另一個模塊,因此'patch('__ main __。somename',somevalue)'有效。 – 2014-12-02 15:29:20

+0

感謝您的快速回答。 if語句確實在模塊級別上。在我的測試課上,我導入了模塊。所以沒有機會重寫單個測試方法? – 2014-12-02 15:35:54