2016-06-10 6 views
-1

나는 파일을 읽고 그 파일의 내용을 기반으로 사전을 만드는 코드를 작성 중이다. 코드는 매우 간단하지만 가장자리의 경우를 테스트하고 싶습니다. my_dict 빈 사전이기 때문에NamedTemporaryFile을 읽을 때 내 주장이 실패하는 이유는 무엇입니까?

from tempfile import NamedTemporaryFile 
from nose.tools import * 

def read_file(filename): 
    with open(filename) as f: 
     my_dict = { dict(line.strip().split(',')) for line in f } 
    return my_dict 

def test_read_file(): 
    file_contents = b"""Hello,World""" 
    with NamedTemporaryFile() as fp: 
     fp.write(file_contents) 
     my_dict = read_file(fp.name) 
    print(my_dict) 
    assert my_dict == { "Hello" : "World" } 

불행하게도이 주장이 실패

여기 내 시도입니다.

나의 이해는 NamedTemporaryFile가 폐쇄되면, 그것은 파괴된다, 그래서 read_filemy_dict이 채워집니다 직접 후 때까지 파괴 기대하지 않습니다. fp이 두 번 열리고 있습니다 : 한 번 쓰고 한 번 읽으십시오 - 괴롭히는 사람입니까?

파일을 읽는 함수를 테스트하는 올바른 방법입니까? 그렇다면 내 주장이 왜 실패 하나? 그렇지 않은 경우이 테스트를 작성하는 데 더 좋은 메커니즘은 무엇입니까?

+0

당신은()'당신이 그것을 읽으려고하기 전에 데이터가 실제로 파일에 기록됩니다 확인하기 위해 fp.flush'호출 할 필요가 있습니다. – chepner

+0

@chepner Ugh, 그게 다야. 답변을 추가하려면 동의하겠습니다. 그래도 거의 속임수예요. – erip

답변

2

읽기 전에 데이터를 쓰려면 쓰기를 플러시해야합니다.

def test_read_file(): 
    file_contents = b"""Hello,World""" 
    with NamedTemporaryFile() as fp: 
     fp.write(file_contents) 
     fp.flush() 
     my_dict = read_file(fp.name) 
    print(my_dict) 
    assert my_dict == { "Hello" : "World" } 
+0

_why_의 질문에 답하기 때문에 이것을 받아들이는 것이 더 나은 방법이기 때문에 다른 대답을 upvoted. – erip

1

실제 파일을 사용하는 대신 메모리 내 파일과 유사한 개체를 사용할 수 있습니다. 이를 위해서는 open을 조롱하거나 파일 이름 대신 파일과 같은 객체를 사용하도록 API를 변경해야합니다.

import unittest.mock 
import io 

def test_read_file(): 
    file_contents = io.BytesIO(b"""Hello,World""") 
    m = unittest.mock.mock_open(read_data=file_contents) 
    with unittest.mock.patch('__main__.open', m): 
     my_dict = read_file("fake.txt") 
    print(my_dict) 
    assert my_dict == { "Hello" : "World" } 
+0

'unittest'는 꽤 미친 것들을 포함합니다! 나는 메모리 내 객체의 아이디어를 좋아한다. – erip