diff --git a/kgb/signature.py b/kgb/signature.py
index b6b6dd5454e8bf294d092f568b275adbbaed0446..19ce354543c2c6e861eb85d25a86d5d104419263 100644
--- a/kgb/signature.py
+++ b/kgb/signature.py
@@ -92,7 +92,7 @@ class BaseFunctionSig(object):
     #: Unbound methods are standard methods on a class.
     TYPE_UNBOUND_METHOD = 2
 
-    def __init__(self, func, owner=_UNSET_ARG):
+    def __init__(self, func, owner=_UNSET_ARG, func_name=None):
         """Initialize the signature.
 
         Subclasses must override this to parse function types/ownership and
@@ -107,10 +107,18 @@ class BaseFunctionSig(object):
                 The owning class, as provided when spying on the function.
                 This is not stored directly (as it may be invalid), but can
                 be used for informative purposes for subclasses.
+
+            func_name (str, optional):
+                An explicit name for the function. This will be used instead
+                of the function's specified name, and is usually a sign of a
+                bad decorator.
+
+                Version Added:
+                    7.0
         """
         self.func = func
         self.func_type = self.TYPE_FUNCTION
-        self.func_name = getattr(func, self.FUNC_NAME_ATTR)
+        self.func_name = func_name or getattr(func, self.FUNC_NAME_ATTR)
         self.owner = None
 
         if hasattr(func, '__func__'):
@@ -291,7 +299,7 @@ class FunctionSigPy2(BaseFunctionSig):
     FUNC_NAME_ATTR = 'func_name'
     METHOD_SELF_ATTR = 'im_self'
 
-    def __init__(self, func, owner=_UNSET_ARG):
+    def __init__(self, func, owner=_UNSET_ARG, func_name=None):
         """Initialize the signature.
 
         Subclasses must override this to parse function types/ownership and
@@ -305,9 +313,18 @@ class FunctionSigPy2(BaseFunctionSig):
                 The owning class, as provided when spying on the function.
                 The value is ignored for methods on which an owner can be
                 calculated, favoring the calculated value instead.
+
+            func_name (str, optional):
+                An explicit name for the function. This will be used instead
+                of the function's specified name, and is usually a sign of a
+                bad decorator.
+
+                Version Added:
+                    7.0
         """
         super(FunctionSigPy2, self).__init__(func=func,
-                                             owner=owner)
+                                             owner=owner,
+                                             func_name=func_name)
 
         func_name = self.func_name
 
@@ -434,7 +451,7 @@ class FunctionSigPy3(BaseFunctionSig):
     FUNC_NAME_ATTR = '__name__'
     METHOD_SELF_ATTR = '__self__'
 
-    def __init__(self, func, owner=_UNSET_ARG):
+    def __init__(self, func, owner=_UNSET_ARG, func_name=None):
         """Initialize the signature.
 
         Subclasses must override this to parse function types/ownership and
@@ -447,9 +464,18 @@ class FunctionSigPy3(BaseFunctionSig):
             owner (type, optional):
                 The owning class, as provided when spying on the function.
                 This is used only when spying on unbound or slippery methods.
+
+            func_name (str, optional):
+                An explicit name for the function. This will be used instead
+                of the function's specified name, and is usually a sign of a
+                bad decorator.
+
+                Version Added:
+                    7.0
         """
         super(FunctionSigPy3, self).__init__(func=func,
-                                             owner=owner)
+                                             owner=owner,
+                                             func_name=func_name)
 
         if not hasattr(inspect, '_signature_from_callable'):
             raise InternalKGBError(
@@ -484,7 +510,26 @@ class FunctionSigPy3(BaseFunctionSig):
         elif '.' in func.__qualname__:
             if owner is not _UNSET_ARG:
                 self.owner = owner
-                self.is_slippery = getattr(owner, func_name) is not func
+
+                try:
+                    self.is_slippery = (
+                        owner is not _UNSET_ARG and
+                        getattr(owner, func_name) is not func
+                    )
+                except AttributeError:
+                    if '<locals>' in func.__qualname__:
+                        logger.warning(
+                            "%r doesn't have a function named \"%s\". This "
+                            "appears to be a decorator that doesn't "
+                            "preserve function names. Try passing "
+                            "func_name= when setting up the spy.",
+                            owner, func_name)
+                    else:
+                        logger.warning(
+                            "%r doesn't have a function named \"%s\". It's "
+                            "not clear why this is. Try passing func_name= "
+                            "when setting up the spy.",
+                            owner, func_name)
 
                 if owner is _UNSET_ARG or inspect.isclass(owner):
                     self.func_type = self.TYPE_UNBOUND_METHOD
diff --git a/kgb/spies.py b/kgb/spies.py
index 6695fc76ec87aa06ceccb3f33bc0c919cd679ab2..014943e19edbcbc4d4035d3981d4343e3c2b6d08 100644
--- a/kgb/spies.py
+++ b/kgb/spies.py
@@ -58,7 +58,7 @@ class FunctionSpy(object):
     _spy_map = {}
 
     def __init__(self, agency, func, call_fake=None, call_original=True,
-                 op=None, owner=_UNSET_ARG):
+                 op=None, owner=_UNSET_ARG, func_name=None):
         """Initialize the spy.
 
         This will begin spying on the provided function or method, injecting
@@ -66,6 +66,11 @@ class FunctionSpy(object):
         what it returned, and adding methods and state onto the function
         for callers to access in order to get those results.
 
+        Version Added:
+            7.0:
+            Added support for specifying an explicit function name using
+            ``func_name=``.
+
         Version Added:
             5.0:
             Added support for specifying an instance in ``owner`` when spying
@@ -104,6 +109,14 @@ class FunctionSpy(object):
                 function (which may happen if the method is decorated and
                 dynamically returns a new function on access), this should
                 be the instance of the object you're spying on.
+
+            func_name (str, optional):
+                An explicit name for the function. This will be used instead
+                of the function's specified name, and is usually a sign of a
+                bad decorator.
+
+                Version Added:
+                    7.0
         """
         # Start off by grabbing the current frame. This will be needed for
         # some errors.
@@ -129,7 +142,8 @@ class FunctionSpy(object):
         # the parameters, making sure everything will be compatible so we
         # don't have unexpected breakages when setting up or calling spies.
         sig = FunctionSig(func=func,
-                          owner=owner)
+                          owner=owner,
+                          func_name=func_name)
         self._sig = sig
 
         # If the caller passed an explicit owner, check to see if it's at all
@@ -175,7 +189,8 @@ class FunctionSpy(object):
                                  'not appear to be a valid function or method.'
                                  % call_fake)
 
-            call_fake_sig = FunctionSig(call_fake)
+            call_fake_sig = FunctionSig(call_fake,
+                                        func_name=func_name)
 
             if not sig.is_compatible_with(call_fake_sig):
                 raise IncompatibleFunctionError(
diff --git a/kgb/tests/py3/test_function_spy.py b/kgb/tests/py3/test_function_spy.py
index 5c8b0e2ee6d7495ebcfa2b5605064f37ec6f7c35..466d9c9fe0b8bbefb24ffbf2d9a6342d90b972b6 100644
--- a/kgb/tests/py3/test_function_spy.py
+++ b/kgb/tests/py3/test_function_spy.py
@@ -1,9 +1,13 @@
+import logging
 import sys
 from unittest import SkipTest
 
 from kgb.tests.base import TestCase
 
 
+logger = logging.getLogger('kgb')
+
+
 class FunctionSpyTests(TestCase):
     """Python 3 unit tests for kgb.spies.FunctionSpy."""
 
@@ -150,3 +154,55 @@ class FunctionSpyTests(TestCase):
         self.assertEqual(len(func.spy.calls), 1)
         self.assertEqual(func.spy.calls[0].args, (2,))
         self.assertEqual(func.spy.calls[0].kwargs, {'b': 2})
+
+    def test_init_with_unbound_method_decorator_bad_func_name(self):
+        """Testing FunctionSpy construction with a decorator not preserving
+        an unbound method name
+        """
+        def bad_deco(func):
+            def _wrapper(*args, **kwargs):
+                return func(*args, **kwargs)
+
+            return _wrapper
+
+        class MyObject(object):
+            @bad_deco
+            def my_method(self):
+                pass
+
+        self.agency.spy_on(logger.warning)
+
+        self.agency.spy_on(MyObject.my_method,
+                           owner=MyObject)
+
+        self.agency.assertSpyCalledWith(
+            logger.warning,
+            "%r doesn't have a function named \"%s\". This "
+            "appears to be a decorator that doesn't "
+            "preserve function names. Try passing "
+            "func_name= when setting up the spy.",
+            MyObject,
+            '_wrapper')
+
+    def test_init_with_unbound_method_decorator_corrected_func_name(self):
+        """Testing FunctionSpy construction with a decorator not preserving
+        an unbound method name and explicit func_name= provided
+        """
+        def bad_deco(func):
+            def _wrapper(*args, **kwargs):
+                return func(*args, **kwargs)
+
+            return _wrapper
+
+        class MyObject(object):
+            @bad_deco
+            def my_method(self):
+                pass
+
+        self.agency.spy_on(logger.warning)
+
+        self.agency.spy_on(MyObject.my_method,
+                           owner=MyObject,
+                           func_name='my_method')
+
+        self.agency.assertSpyNotCalled(logger.warning)
