diff options
| author | 2020-05-10 17:47:09 -0700 | |
|---|---|---|
| committer | 2020-05-11 12:03:11 -0700 | |
| commit | 34b836a8eba0f006c77a7b3f48f7ab14c37d31ee (patch) | |
| tree | 8b34a7862c490e6fe5b2ac694bd29db353919c0a /tests | |
| parent | Test token regex doesn't match invalid tokens (diff) | |
Fix autospec decorator when used with multiple attributes
The original approach of messing with the `attribute_name` didn't work
for reasons I won't discuss here (would require knowledge of patcher
internals). The new approach doesn't use patch.multiple but mimics it by
applying multiple patch decorators to the function. As a consequence,
this can no longer be used as a context manager.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/helpers.py | 28 | 
1 files changed, 12 insertions, 16 deletions
| diff --git a/tests/helpers.py b/tests/helpers.py index 1ab8b455f..dfbe539ec 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -24,25 +24,21 @@ for logger in logging.Logger.manager.loggerDict.values():  def autospec(target, *attributes: str, **kwargs) -> unittest.mock._patch: -    """ -    Patch multiple `attributes` of a `target` with autospecced mocks and `spec_set` as True. - -    To allow for arbitrary parameter names to be used by the decorated function, the patchers have -    no attribute names associated with them. As a consequence, it will not be possible to retrieve -    mocks by their attribute names when using this as a context manager, -    """ +    """Patch multiple `attributes` of a `target` with autospecced mocks and `spec_set` as True."""      # Caller's kwargs should take priority and overwrite the defaults.      kwargs = {'spec_set': True, 'autospec': True, **kwargs} -    attributes = {attribute: unittest.mock.DEFAULT for attribute in attributes} - -    patcher = unittest.mock.patch.multiple(target, **attributes, **kwargs) - -    # Unset attribute names to allow arbitrary parameter names for the decorator function. -    patcher.attribute_name = None -    for additional_patcher in patcher.additional_patchers: -        additional_patcher.attribute_name = None -    return patcher +    # Import the target if it's a string. +    # This is to support both object and string targets like patch.multiple. +    if type(target) is str: +        target = unittest.mock._importer(target) + +    def decorator(func): +        for attribute in attributes: +            patcher = unittest.mock.patch.object(target, attribute, **kwargs) +            func = patcher(func) +        return func +    return decorator  class HashableMixin(discord.mixins.EqualityComparable): | 
