I have a class, QueryBuilder
, which sends the message build
to an instance of another class, Query
. The method that sends that message is called build_query
. For the purpose of this question, I'm only concerned with what values QueryBuilder
sends to Query
's build
method.
My test for QueryBuilder
asserts that Query
's build
method is called once for each set of "grouped params" sorted by QueryBuilder
.
def test_groups_queries_based_on_config(self):
params = {'metatag_attr': 'name', 'metatag_val': 'description', 'robots': True}
with patch.object(Query, 'build') as mock_query_build:
self.query_builder.build_queries(params)
calls = [call({'metatag_attr': 'name', 'metatag_val': 'description'}),
call({'robots': True})]
mock_query_build.assert_has_calls(calls)
Here is the code for QueryBuilder
.
class QueryBuilder(object):
def __init__(self, config=None):
self._queries = []
self._collected_params = None
self._config = config or {}
...
def build_queries(self, params):
# should return an iterator of built queries
self._collected_params = params
for param_set in self._group_params():
query = self.build_query(param_set)
self._append_query(query)
return self._queries
def build_query(self, param_set):
query = self._new_query()
return query.build(param_set)
### Private ###
def _new_query(self):
return Query(shortcuts=self.shortcuts, option_groups=self.options)
def _append_query(self, query):
valid_query = {k: v for k, v in query.items() if not k == 'seo_attr'}
if not valid_query:
return
self._queries.append(query)
def _group_params(self):
# initialize list to collect all params
grouped_params = []
# add the option params to the list
options = self._get_options()
grouped_params.extend(options)
# add the shortcut params to the list
shortcuts = self._get_shortcuts()
grouped_params.extend(shortcuts)
return grouped_params
...
Some private methods and public properties have been left out because I don't believe they pertain to the question.
The issue is that after I added this line to QueryBuilder
's private _append_query
method...
valid_query = {k: v for k, v in query.items() if not k == 'seo_attr'}
if not valid_query:
return
...I'm now getting several extra calls to the build
method, causing my test to fail. These are the extra calls to build
:
E Expected: [call({'metatag_val': 'description', 'metatag_attr': 'name'}), call({'robots': True})]
E Actual: [call({'metatag_val': 'description', 'metatag_attr': 'name'}),
E call().items(),
E call().items().__iter__(),
E call({'robots': True}),
E call().items(),
E call().items().__iter__()]
I don't see how sending items
to query
in the dict comprehension is treated as a call to build
again. What would explain this?
Aucun commentaire:
Enregistrer un commentaire