I am writing some unit test and encountered a odd behavior from SeqIO in biopython. I have reproduced the problem in the following script
import mock
from Bio import SeqIO
FAKE_FASTA_CONTENT = '''>1
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>2
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>3
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
'''
# https://docs.python.org/3.3/library/unittest.mock.html
m = mock.mock_open(read_data=FAKE_FASTA_CONTENT)
with mock.patch('__main__.open', m, create=True):
with open('foo') as inf:
io = SeqIO.parse(inf, 'fasta')
for k, rec in enumerate(io):
print(rec)
The output is
ID: 1
Name: 1
Description: 1
Number of features: 0
Seq('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...AAA', SingleLetterAlphabet())
ID: 2
Name: 2
Description: 2
Number of features: 0
Seq('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...AAA', SingleLetterAlphabet())
I wonder why it cannot find the third (also last) sequence from the input.
pasting FAKE_FASTA_CONTENT into a text file does work, but what's going on in this testcase? How does SeqIO do parsing?
You are using an weird mock object - and it is not all that clear what that does. Perhaps that mock object is not as direct replacement as you think. Why not use a StringIO object instead. That is really that is supposed to imitate a string being used as a file.
mock is not weird. I was trying to mock out an
open
call in a module when writing unittests for it, that's why mock I am using mock. But it appears that implementation of mock_open().readline isn't exactly like a file handle, it's more of an iterator.Is there a way to do mocking with StringIO, too?
what I meant by 'weird' was that it claims to do something but it does not actually do it exactly the same way - which it turned out to be the case. StringIO is a way to create a filehandle to a string as if it were a file that can then be passed to objects expecting a filehandle. It can be used during testing.
I think it agreeable that in this case, the mock_open object should be improved to be more like a file handle. FYI, it doesn't support
__iter__
either, sofor line in inf
won't work for the mock object unless__iter__
method is explicitly written during testing.