I've got a class with a function that adds unstaged changes in a git repo and commits them
def commit_local_changes(self, repo_path):
repo = Repo(repo_path)
changed_files = repo.git.diff(None, name_only=True).splitlines()
if changed_files:
for file in changed_files:
repo.git.add(file)
repo.git.commit("-m", "some commit message")
return repo.head.object.hexsha
I'm trying to write unit tests to go over this functionality and I was to have repo.git.diff(None, name_only=True)
actually return something besides a mock. I've tried to set up the tests like so:
@patch("myModule.Repo")
def test_commit_local_changes(self, mock_repo):
mock_repo.return_value
.git.return_value
.diff.return_value = 'file1\nfile2'
but when I print changed_files
in the main method and call the mock I see that it's just some MagicMock:
<MagicMock name='Repo().git.diff().splitlines()' id='140551053340304'>
My issue was a lack of understanding of Python's attribute mocking versus return value for a function result.
In my case, Repo() is a function creating an instance of the class Repo (python may have different names for these, I'm more familiar with Java). So I needed to mock the return value of Repo(), then Python will mock it's attributes for me, then I needed to mock the return value of the call to diff(). The following worked:
mock_repo.return_value.git.diff.return_value = "file1\nfile2"