2017-11-09 6 views
0

기본 작업이있는 사용자 정의 Db 클래스가 있습니다. 나는 그 주위에 테스트를 작성하려고 노력하고있다 - 나의 클래스의 __init__에 내가 피하고 싶은 실제 db에 연결하고있다. (단위 테스트를 작성하고 있기 때문에 실제 db에 연결할 필요가 없다.) pytest : 내 클래스의 __init__을 모의 할 수 없습니다.

내 코드입니다 :

@mock.patch('mydb.Db') 
@pytest.mark.parametrize("input,expected", [ 
    (
     { 
      'key' : "x" , 
      'value' : 5 , 
     } , 
     [ "x = 5" ] 
    ) , 
    ]) 
def test_where_statement(mock_db, input, expected): 
    mock_db.__init__.return_value = None 
    assert expected == mock_db.where(input[ "key"] , input[ "value" ])._condition_list 

그것은 내가 없음으로 RETURN_VALUE를 설정 라인에 실패 - 문제는 다음과 같습니다

def test_where_statement(mock_db, input, expected): 
>  mock_db.__init__.return_value = None 
E  AttributeError: 'instancemethod' object has no attribute 'return_value' 

내가 할 만 init 함수를 조롱하고 싶어 where 함수를 실행할 수 있습니다 (예를 들어 내 쿼리의 where 문을 빌드합니다).

무엇이 누락 되었습니까?

+0

테스트 파일에서'Db' 가져 오기를 패치하고 있습니까? – dm03514

+0

@ dm03514 무엇을 의미합니까? 나는'mydb import Db'를 내 테스트 파일 위에 올려 놓았습니다. – ghostrider

+0

@ghostrider 내 업데이트 된 답변을 확인하십시오. – erhesto

답변

1

AFAIK 여기에는 두 가지 방법이 있습니다. 하나는 __init__ 메서드를 직접 패치하여 예상대로 작동합니다 (원래 __init__는 호출되지 않습니다).

@mock.patch('mydb.Db.__init__', return_value=None) 

둘째, 대신 인스턴스를 얻기 위해 호출되는 mock_db하는 RETURN_VALUE을 할당 (개체가 모의가 이미 같은 길을 따라 호출 할 수 없습니다 것) __init__ 방법을 mock_db 할 수 없음 값을 할당하는 현재의 접근 방식 Db 클래스 (mock_db.return_value는 Db 인스턴스의 모의 버전을 가리켜 야 함)를 사용하거나 코드가 실행될 때 얻을 수있는 기본 모의 동작을 변경하는 데 관심이 없다면 그대로 두십시오 (클래스 호출시 AFAIR). 인스턴스를 생성하기 위해 일부 모의 객체가 자동으로 생성됩니다.

편집 : mydb를 적절한 위치에서 조롱해야합니다. 엄지 손가락의 규칙은 가져온 위치가 아닌 위치를 조롱하는 것입니다. 즉, 파일에있는 코드를 테스트하려면 import mydb이 있고 my_package.my_module.mydb.Db 패치가 필요합니다.

다양한 자원에 대한 모의 객체 : 내밀어해야 할 첫 번째 것들 중 ELI5 mocks explained

하나는 우리가 mymodule.os에있는 객체를 조롱하는 mock.patch 방법 데코레이터를 사용하고 있음을 주입하고 있다는 것입니다 우리의 테스트 케이스 메소드를 조롱해라. mymodule.os에서 참조하는 것보다 os 자체를 조롱하는 것이 더 합리적이지 않습니까?

글쎄 파이썬은 모듈을 가져오고 관리 할 때 다소 비열한 뱀입니다. 런타임시, mymodule 모듈은 자체 os를 가지며 모듈의 자체 로컬 범위로 가져옵니다. 따라서 우리가 os를 모의한다면, 우리는 mymodule 모듈에서 mock의 효과를 보지 않을 것입니다. 계속 반복하는 내용은 다음과 같습니다.

출처가 아닌 항목을 모의합니다.

+0

첫 번째 시도하고 내 db에 액세스하려고했기 때문에 __init__ 호출 한 것 같아요. – ghostrider

+0

mydb를 올바른 위치에서 조롱 했습니까? 엄지 손가락의 규칙은 가져온 위치가 아닌 위치를 조롱하는 것입니다. 즉,'import mydb' 파일을 가지고있는'my_package.my_module' 파일에있는 코드를 테스트하려면'my_package.my_module.mydb.Db'를 패치해야합니다. – erhesto