diff --git a/tests/regressiontests/base_handler/__init__.py b/tests/regressiontests/base_handler/__init__.py
new file mode 100644
diff --git a/tests/regressiontests/base_handler/middleware.py b/tests/regressiontests/base_handler/middleware.py
new file mode 100644
--- /dev/null
+++ b/tests/regressiontests/base_handler/middleware.py
@@ -0,0 +1,25 @@
+"""
+Middleware to help test django.core.handlers.base.BaseHandler
+"""
+from django.http import HttpResponse
+
+class ProcessRequestException(Exception):
+    pass
+
+class ProcessViewException(Exception):
+    pass
+
+
+class ProcessExceptionResponse:
+    def process_exception(self, request, exception):
+        return HttpResponse('OK')
+
+
+class ProcessRequestRaise:
+    def process_request(self, request):
+        raise ProcessRequestException()
+
+
+class ProcessViewRaise:
+    def process_view(self, request, view_func, *view_args, **view_kwargs):
+        raise ProcessViewException()
diff --git a/tests/regressiontests/base_handler/models.py b/tests/regressiontests/base_handler/models.py
new file mode 100644
diff --git a/tests/regressiontests/base_handler/tests.py b/tests/regressiontests/base_handler/tests.py
new file mode 100644
--- /dev/null
+++ b/tests/regressiontests/base_handler/tests.py
@@ -0,0 +1,101 @@
+"""
+Tests for django.core.handlers.base.BaseHandler
+"""
+from django.test import TestCase
+from django.conf import settings
+from django.core.handlers.base import BaseHandler
+from django.http import HttpRequest
+from middleware import (ProcessRequestException, ProcessViewException,
+    ProcessExceptionResponse, ProcessRequestRaise, ProcessViewRaise)
+
+
+class BaseHandlerTestCase(TestCase):
+
+    def setUp(self):
+        self.middleware_classes = settings.MIDDLEWARE_CLASSES
+
+        # Tests want uncaught exceptions to fall through
+        self.debug_propagate_exceptions = settings.DEBUG_PROPAGATE_EXCEPTIONS
+        settings.DEBUG_PROPAGATE_EXCEPTIONS = True
+
+        self.handler = BaseHandler()
+
+    def tearDown(self):
+        # reset settings changes
+        settings.MIDDLEWARE_CLASSES = self.middleware_classes
+        settings.DEBUG_PROPAGATE_EXCEPTIONS = self.debug_propagate_exceptions
+
+    def _get_request(self, path):
+        request = HttpRequest()
+        request.META = {
+            'SERVER_NAME': 'testserver',
+            'SERVER_PORT': 80,
+        }
+        request.path = request.path_info = "/base_handler/%s" % path
+        return request
+
+    def test_process_request_raises_uncaught(self):
+        """
+        Exceptions generated in <Middleware>.process_request() should propagate uncaught.
+        """
+        settings.MIDDLEWARE_CLASSES = (
+            'regressiontests.base_handler.middleware.ProcessRequestRaise',
+        )
+
+        self.handler.load_middleware()
+
+        self.assertRaises(
+            ProcessRequestException,
+            self.handler.get_response,
+            self._get_request('path/')
+        )
+
+    def test_process_view_raises_uncaught(self):
+        """
+        Exceptions generated in <Middleware>.process_view() without any
+        process_exception handlers should propagate uncaught.
+        """
+        settings.MIDDLEWARE_CLASSES = (
+            'regressiontests.base_handler.middleware.ProcessViewRaise',
+        )
+
+        self.handler.load_middleware()
+
+        self.assertRaises(
+            ProcessViewException,
+            self.handler.get_response,
+            self._get_request('path/'),
+        )
+
+    def test_view_raises_caught(self):
+        """
+        Ticket #12250. A view that generates an exception and a middleware
+        whose process_exception() provides a response. Result should be that
+        response.
+        """
+        settings.MIDDLEWARE_CLASSES = (
+            'regressiontests.base_handler.middleware.ProcessExceptionResponse',
+        )
+
+        self.handler.load_middleware()
+        response = self.handler.get_response(self._get_request('view_that_raises_exc/'))
+
+        # Handled exception yields a valid response
+        self.assertEqual(response.status_code, 200)
+
+    def test_process_view_raises_caught(self):
+        """
+        A <Middleware>.process_view() that generates an exception and another
+        middleware whose process_exception() provides a response. Result should
+        be that response.
+        """
+        settings.MIDDLEWARE_CLASSES = (
+            'regressiontests.base_handler.middleware.ProcessViewRaise',
+            'regressiontests.base_handler.middleware.ProcessExceptionResponse',
+        )
+
+        self.handler.load_middleware()
+        response = self.handler.get_response(self._get_request('path/'))
+
+        # Handled exception yields a valid response
+        self.assertEqual(response.status_code, 200)
diff --git a/tests/regressiontests/base_handler/urls.py b/tests/regressiontests/base_handler/urls.py
new file mode 100644
--- /dev/null
+++ b/tests/regressiontests/base_handler/urls.py
@@ -0,0 +1,7 @@
+from django.conf.urls.defaults import patterns
+import views
+
+urlpatterns = patterns('',
+    (r'^path/$', views.view),
+    (r'^view_that_raises_exc/$', views.view_that_raises_exc),
+)
diff --git a/tests/regressiontests/base_handler/views.py b/tests/regressiontests/base_handler/views.py
new file mode 100644
--- /dev/null
+++ b/tests/regressiontests/base_handler/views.py
@@ -0,0 +1,10 @@
+from django.http import HttpResponse
+
+class ViewException(Exception):
+    pass
+
+def view(request):
+    return HttpResponse('OK')
+
+def view_that_raises_exc(request):
+    raise ViewException()
diff --git a/tests/urls.py b/tests/urls.py
--- a/tests/urls.py
+++ b/tests/urls.py
@@ -45,4 +45,7 @@
 
     # test util views
     (r'test_utils/', include('regressiontests.test_utils.urls')),
+
+    # base_handler views
+    (r'base_handler/', include('regressiontests.base_handler.urls')),
 )
