diff --git a/AUTHORS b/AUTHORS
index bf10e80afd..4adfe2310b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -650,6 +650,7 @@ answer newbie questions, and generally made Django that much better:
     Thomas Sorrel
     Thomas Steinacher 
     Thomas Stromberg 
+    Thomas Tanner 
     tibimicu@gmx.net
     Tim Graham 
     Tim Heap 
diff --git a/django/test/client.py b/django/test/client.py
index b2633bd7e7..62f7c5fb6c 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -195,20 +195,25 @@ def encode_multipart(boundary, data):
 
 def encode_file(boundary, key, file):
     to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET)
+    filename = os.path.basename(file.name) if hasattr(file, 'name') else ''
     if hasattr(file, 'content_type'):
         content_type = file.content_type
+    elif filename:
+        content_type = mimetypes.guess_type(filename)[0]
     else:
-        content_type = mimetypes.guess_type(file.name)[0]
+        content_type = None
 
     if content_type is None:
         content_type = 'application/octet-stream'
+    if not filename:
+        filename = key
     return [
         to_bytes('--%s' % boundary),
         to_bytes('Content-Disposition: form-data; name="%s"; filename="%s"'
-                 % (key, os.path.basename(file.name))),
+                 % (key, filename)),
         to_bytes('Content-Type: %s' % content_type),
         b'',
-        file.read()
+        to_bytes(file.read())
     ]
 
 
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index d95599f613..375a39920f 100644
--- a/docs/releases/1.8.txt
+++ b/docs/releases/1.8.txt
@@ -511,6 +511,8 @@ Tests
   :meth:`TestCase.setUpTestData() `. Using
   this technique can speed up the tests as compared to using ``setUp()``.
 
+* Added test client support for file uploads with file-like objects.
+
 Validators
 ^^^^^^^^^^
 
diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt
index 454da239e0..69649d7a2e 100644
--- a/docs/topics/testing/tools.txt
+++ b/docs/topics/testing/tools.txt
@@ -238,6 +238,13 @@ Use the ``django.test.Client`` class to make requests.
         (The name ``attachment`` here is not relevant; use whatever name your
         file-processing code expects.)
 
+        You may also provide any file-like object (e.g., :class:`~io.StringIO` or
+        :class:`~io.BytesIO`) as a file handle.
+
+        .. versionadded:: 1.8
+
+            The ability to use a file-like object was added.
+
         Note that if you wish to use the same file handle for multiple
         ``post()`` calls then you will need to manually reset the file
         pointer between posts. The easiest way to do this is to
diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py
index 85363744d8..37954a99ca 100644
--- a/tests/file_uploads/tests.py
+++ b/tests/file_uploads/tests.py
@@ -17,7 +17,7 @@ from django.test import TestCase, client
 from django.test import override_settings
 from django.utils.encoding import force_bytes
 from django.utils.http import urlquote
-from django.utils.six import StringIO
+from django.utils.six import BytesIO, StringIO
 
 from . import uploadhandler
 from .models import FileModel
@@ -262,6 +262,34 @@ class FileUploadTests(TestCase):
             self.assertLess(len(got), 256,
                             "Got a long file name (%s characters)." % len(got))
 
+    def test_file_content(self):
+        tdir = tempfile.gettempdir()
+
+        file = tempfile.NamedTemporaryFile
+        with file(suffix=".ctype_extra", dir=tdir) as no_content_type, \
+                file(suffix=".ctype_extra", dir=tdir) as simple_file:
+            no_content_type.write(b'no content')
+            no_content_type.seek(0)
+
+            simple_file.write(b'text content')
+            simple_file.seek(0)
+            simple_file.content_type = 'text/plain'
+
+            string_io = StringIO('string content')
+            bytes_io = BytesIO(b'binary content')
+
+            response = self.client.post('/echo_content/', {
+                'no_content_type': no_content_type,
+                'simple_file': simple_file,
+                'string': string_io,
+                'binary': bytes_io,
+            })
+            received = json.loads(response.content.decode('utf-8'))
+            self.assertEqual(received['no_content_type'], 'no content')
+            self.assertEqual(received['simple_file'], 'text content')
+            self.assertEqual(received['string'], 'string content')
+            self.assertEqual(received['binary'], 'binary content')
+
     def test_content_type_extra(self):
         """Uploaded files may have content type parameters available."""
         tdir = tempfile.gettempdir()