Mocking os.stat in Python


8th of November 2009

I have some code that checks that a file is treated differently if some time has passed. In other words, it reacts if the modification time is more than it was before. The code uses os.stat(filename)[stat.ST_MTIME] to do this. The challenge was to mock os.stat so that I can pretend some time has passed without having to wait. Here was my first solution which made running many tests sloooow:

 def test_file_changed(self):
     filename = 'foo.txt'
     expect_timestamp = int(time.time())
     ...run the unit test with 'expect_timestamp'...
     time.sleep(1)
     expect_timestamp += 1
     ...run the unit test with 'expect_timestamp'...

So, here's how I mock os.stat to avoid having to do the time.sleep(1) in the test:

 def test_file_changed(self):
     filename = 'foo.txt'
     expect_timestamp = int(time.time())
     ...run the unit test with 'expect_timestamp'...
     import os
     from posix import stat_result
     def fake_stat(arg):
         if arg == filename:
             faked = list(orig_os_stat(arg))
             faked[stat.ST_MTIME] = faked[stat.ST_MTIME] + 1
             return stat_result(faked)
         else:
             return orig_os_stat(arg)
     orig_os_stat = os.stat
     os.stat = fake_stat

     expect_timestamp += 1
     ...run the unit test with 'expect_timestamp'...

I hope this helps someone else who's trying to do the same. It took me some time to figure out that os.stat is used by lots of various sub routines in the os module so it's important to only mock the relevant argument otherwise you might get unexpected problems.



Comment

Show all 4 comments
 
Name:
Email:
hide my email address.

Your email address will be encoded to prevent email-extraction spiders from reading it so you won't get spammed if you decide to show your email address.