2016-07-27 66 views
1

我已經寫了一段代碼,使用一個配置文件(以JSON格式)單元測試 - assertRaises返回一個錯誤,而不是通過

def test_read_config_file(self): 
    self.assertRaises(ValueError, self.read_config_file('no_json.txt') 

原有的功能看起來像這樣的:

def read_config_file(file_name) 
    config_data = None 

    try: 
     with open(file_name, 'r') as infile: 
     config_data = json.load(infile) 
    except ValueError as err: 
     LOGGER.error(str(err)) 

    return config_data 

當我跑我的測試用例我得到這個:

2016-07-27 12:41:09,616 ERROR read_config_file(158) No JSON object could be decoded 
2016-07-27 12:41:09,616 ERROR read_config_file(158) No JSON object could be decoded 
2016-07-27 12:41:09,616 ERROR read_config_file(158) No JSON object could be decoded 
2016-07-27 12:41:09,616 ERROR read_config_file(158) No JSON object could be decoded 

no_json.txt只包含 「嗨」。爲什麼我在這裏得到4錯誤?

感謝,

+0

能有什麼辦法? 「你好」是無效的JSON,所以錯誤被記錄。它似乎不是測試結果。相反,它看起來像一個印刷品。 – Sadik

+0

在文檔中有一個使用'with'語句處理斷言的例子。你的'read_config_file'函數也通過記錄來處理異常。如果你希望你的函數在記錄後提高ValueError,那麼你應該在異常子句中記錄後寫'raise'來重新提高它。 –

+0

@Zazz你應該接受一個答案,如果它幫助你。 – Wombatz

回答

0

你沒有正確使用unittest庫。當你這樣寫:

def test_read_config_file(self): 
    self.assertRaises(ValueError, self.read_config_file('no_json.txt')) 
    # Btw. there was a missing closing `)` 

self.read_config_file()方法是self.assertRaises之前執行。如果失敗,將永遠不會調用self.assertRaises。相反,異常會冒出來,直到其他東西出現。

您希望self.assertRaises方法執行self.read_config_file方法。因爲那時只有它才能捕獲潛在的ValueError。要做到這一點,你有兩個選擇:

傳遞測試方法和單獨的參數:

self.assertRaises(ValueError, self.read_config_file, "no_json.txt") 

像這樣self.assertRaises會叫你到它通過與指定的參數的函數。然後在self.assertRaises內發生異常,它可以被捕獲並讓測試成功。

第二個選擇是使用上下文管理器:

def test_read_config_file(self): 
    with self.assertRaises(ValueError): 
     self.read_config_file("no_json.txt") 

像這樣的異常將with語句內發生。在上下文管理器的清理步驟中,這種異常的出現可以再次讓測試成功。

編輯: 從您的編輯,我可以看到你已經在你的self.read_config_file方法處理ValueError。所以任何self.assertRaises方法都會失敗。或者讓self.read_config_file提高錯誤或更改測試。

+0

嗯...是不是assertRaises點來檢查是否引發異常的函數實際上在發生異常時引發異常?或者我在這裏錯過了什麼? – Zazz

+0

是的,如果期望的異常是__not__引發,則assertRaises __fails__。但是,你的代碼中的兩個問題(assertRaises的不正確使用,甚至沒有將代碼中的異常拋向文本)使得該測試毫無意義。我的回答中有些東西不夠清楚?請指出任何不清楚的地方,我會盡量說清楚。 – Wombatz

0

問題是您的函數捕獲ValueError例外,json.load引發,執行日誌記錄,然後繼續返回值config_data。你的測試聲稱函數應該引發一個異常,但是沒有代碼來確保函數能夠做到這一點。

解決這一問題將是增加一個raise聲明,以確保ValueError重新提出由assertRaises呼叫被困修改的代碼最簡單的方法:

def read_config_file(file_name) 
    config_data = None 

    try: 
     with open(file_name, 'r') as infile: 
      config_data = json.load(infile) 
    except ValueError as err: 
     LOGGER.error(str(err)) 
     raise 

    return config_data 
相關問題