2017-09-29 8 views
0

을 구성하는 방법의 로거 출력의 하위 문자열을 주장 나는 예를 들어, 기록 된 뭔가를 주장하는 방법에 대한 많은 예를 발견했다 메시지가 생성 된 특정한 방법으로부터 단언. 이 테스트는 기록되는 특정 ID에만 관심이 있습니다.파이썬 - <a href="http://www.michaelpollmeier.com/python-mock-how-to-assert-a-substring-of-logger-output" rel="nofollow noreferrer">http://www.michaelpollmeier.com/python-mock-how-to-assert-a-substring-of-logger-output</a></p> <p>그러나 나는를 분리하는 방법을 모르는 관계없이 메시지가

테스트 코드

mock_logger.warn.assert_called_with(
    all_match(
     contains_string('user-id'), 
     contains_string('team-id') 
    ) 
) 

(로거는 메시지 조립) 모두

생산 코드 1을 위해 일해야 :

logger.warn(
    "Order for team %s and user %s could not be processed", 
    'team-id', 
    'user-id' 
) 

생산 코드 2 (우리가 조립을 메시지 및 예외 포함) :

logger.warn(
    "Order for team {} and user {} could not be processed" 
    .format('team-id', 'user-id'), 
    ex 
) 

하지만 난이 인수를 캡처하거나 사용자 정의 로그 펜더를 설정하고 최종 메시지의 주장을 하나 생각하고 같이이 작동하지 않습니다. 내가 IDE에서 코드를 작성하지 않은으로


오타/잠재적 구문 오류를 무시하십시오

답변

0

당신이 원하는 경우 여러 인수를 가지고 문자열 자체, I를 형식으로 warn 방법 일치하는 사람이 all_match과 같다고 생각하지 마십시오. Matchers는 단일 인수 만 일치시킵니다.

당신은 assert_called_with 인수로 all_match을 전달하는, 그래서 그것은 단지 mock_logger.warn에 호출에 인수를 일치시킬 수 있습니다. 이것이 테스트 코드가 생산 코드 1이 아닌 생산 코드 2에 전달되는 이유입니다.

생산 코드 2에서는 warn의 첫 번째 인수는 "Order for team team-id and user user-id could not be processed" 문자열입니다. 가짜는 첫 번째 인수를 all_match으로 전달하므로 찾고자하는 것을 찾을 수 있습니다.

생산 코드 1에서는 warn에 대한 첫 번째 인수는 "Order for team %s and user %s could not be processed"입니다. 그것은 all_match이 알고있는 모든 것입니다. 두 번째와 세 번째 인수는 all_match이 찾고자하는 문자열을 포함하지만 액세스 할 수는 없습니다.

정규 표현식을 assert_called_with으로 전달하는 대신 수동으로 모의 호출을 확인하는 것이 두 경우에 모두 적용됩니다. 당신이 정말 정규를 사용하려면

mock_logger = unittest.Mock() 
... 
# Call production code 
... 
calls = mock_logger.warn.call_args_list # gets a list of calls made to the mock 

first_call = calls[0] # each call object in call_args_list is a tuple containing 2 tuples: ((positional args), (keyword args)). Let's grab the first one. 

arguments = first_call[0] # the positional arguments are the first tuple in the call 

if len(arguments) == 1: # If warn got 1 argument, it's a string. Look for 'team-id' and 'user-id' in that argument 
    self.assertIn('team-id', arguments[0]) 
    self.assertIn('user-id', arguments[0]) 
elif len(arguments) == 3: # if warn got 3 arguments, 'team-id' and 'user-id' should have been the 2nd and 3rd arguments. 
    self.assertEqual("Order for team %s and user %s could not be processed", arguments[0]) 
    self.assertEqual('team-id', arguments[1]) 
    self.assertEqual('user-id', arguments[2]) 

하면, 당신은 항상 당신이 warn를 호출하기 전에 문자열을 포맷 즉, logger.warn 단일 문자열을 전달해야합니다 : 여기에 무슨 뜻인지의 우아하지만 읽을 구현입니다.