Mocking a file read in python3 for testing

So for a personal project I had to prove, and ensure that a hashing function always returned hex characters. The hashing function would open a given file, read it in chunks, and then spit out a hex digest (for storage as text in a database).

Here is my thing/Util.py:

import hashlib

class Util(object):

    @staticmethod
    def hash_file(fullpath, blocksize=65536):
        print('!' * 20)
        hasher = hashlib.sha256()
        afile = open(fullpath, 'rb')
        buf = afile.read(blocksize)
        while len(buf) > 0:
            hasher.update(buf)
            buf = afile.read(blocksize)
        afile.close()
        return hasher.hexdigest()

And here is my tests/test_utils.py, written in python3.4 and using fudge and pure python to the open(), read() and close() calls out:

import builtins
import fudge

from thing.util import Util

@fudge.test
def test_hash_file(monkeypatch):

    fake_buffer = b'test'

    fake_empty_buffer = b''

    fake_filehandle = (fudge.Fake('file').provides('read')
        .with_args(65536).returns(fake_buffer)
        .next_call()
        .with_args(65536).returns(fake_empty_buffer)
        .provides('close'))

    fake_open = (fudge.Fake('open').expects_call()
        .with_args('/a/folder/0.ext', 'rb')
        .returns(fake_filehandle))

    monkeypatch.setattr(builtins, "open", fake_open)

    assert "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" \
        == Util.hash_file('/a/folder/0.ext')

The biggest gotchya here is that most tutorials and blog posts on this subject are written for python2, and don’t take into account the fact that __builtin__ has become builtins.

One Comment

  1. […] is a follow-up to my previous post, where I described a┬ámanner in which you can mock a file-like object with fudge in python […]

Leave a Reply

*

Contact Nixz Kerr