How can I assert calls that accept sequence arguments with Python Mock?

mocking, python, unit-testing

Solution

I haven't touched the code I was originally working with for a good while, but I've been reconsidering my approach to testing in general. I've been trying to be more careful about what I do and don't mock. I recently realized that I was unconsciously starting to following this rule of thumb: mock something if it makes my test shorter and simpler and leave it alone if it makes the test more complicated. Simple input/output testing suffices in the case of this method. There are no external dependencies like a database or files. So in short, I think the answer to my question is, "I shouldn't mock `calculate_something`." Doing so makes my test harder to read and maintain.

Problem

I am processing a sequence of user-defined objects. It looks similar to the following: ``` class Thing(object): def __init__(self, x, y): self.x = x self.y = y ``` The method I am currently testing has functionality similar to the following: ``` def my_function(things): x_calc = calculate_something(t.x for t in things) y_calc = calculate_something(t.y for t in things) return x_calc / y_calc ``` The problem I am facing is testing the calls to `calculate_something`. I want to assert that these calls happened, something like so: ``` calculateSomethingMock.assert_any_call(the_sequence) ``` I don't care about the order of the sequence passed into `calculate_something`, but I do care that the elements are all present. I could wrap the generator function in a call to `set`, but I don't feel like my test should be dictating what type of sequence is passed into `calculate_something`. I should be able to pass it any kind of sequence. I could alternatively create a method that generates the sequence instead of using generator syntax and mock that method, but that seems like overkill. How can I best structure this assertion, or is my trouble testing here an indication of poorly structured code? I am using Python 2.7.3 with Mock 1.0.1. (For anyone who feels compelled to comment on it, I'm aware I'm doing test last and that this isn't considered the greatest practice.) Edit: After watch this marvelous talk entitled "Why You Don't Get Mock Objects by Gregory Moeck", I have reconsidered whether I should even be mocking the `calculate_something` method.

Original source