diff --git a/packages/flutter_tools/test/devfs_test.dart b/packages/flutter_tools/test/devfs_test.dart
index 1887e74..b8d93d4 100644
--- a/packages/flutter_tools/test/devfs_test.dart
+++ b/packages/flutter_tools/test/devfs_test.dart
@@ -4,17 +4,15 @@
 
 import 'dart:async';
 import 'dart:convert';
+import 'dart:io'; // ignore: dart_io_import
 
 import 'package:file/file.dart';
 import 'package:file/memory.dart';
-import 'package:flutter_tools/src/base/context.dart';
 import 'package:flutter_tools/src/base/file_system.dart';
 import 'package:flutter_tools/src/base/io.dart';
-import 'package:flutter_tools/src/base/platform.dart';
 import 'package:flutter_tools/src/devfs.dart';
 import 'package:flutter_tools/src/vmservice.dart';
 import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
-import 'package:mockito/mockito.dart';
 
 import 'src/common.dart';
 import 'src/context.dart';
@@ -22,39 +20,17 @@
 
 void main() {
   FileSystem fs;
-  MockPlatform mockPlatform;
+  String filePath;
+  Directory tempDir;
+  String basePath;
+  DevFS devFS;
 
-  setUp(() {
-    fs = MemoryFileSystem(style: FileSystemStyle.posix);
-    mockPlatform = MockPlatform();
-    when(mockPlatform.pathSeparator).thenReturn('/');
-    when(mockPlatform.isWindows).thenReturn(false);
+  setUpAll(() {
+    fs = MemoryFileSystem();
+    filePath = fs.path.join('lib', 'foo.txt');
   });
 
   group('DevFSContent', () {
-    test('copyToFile', () {
-      final String filePath = fs.path.join('lib', 'foo.txt');
-      final File file = fs.file(filePath)
-        ..createSync(recursive: true)
-        ..writeAsStringSync('hello, world');
-      final DevFSByteContent byteContent = DevFSByteContent(<int>[4, 5, 6]);
-      final DevFSStringContent stringContent = DevFSStringContent('some string');
-      final DevFSFileContent fileContent = DevFSFileContent(file);
-
-      final File byteDestination = fs.file('byte_dest');
-      final File stringDestination = fs.file('string_dest');
-      final File fileDestination = fs.file('file_dest');
-
-      byteContent.copyToFile(byteDestination);
-      expect(byteDestination.readAsBytesSync(), <int>[4, 5, 6]);
-
-      stringContent.copyToFile(stringDestination);
-      expect(stringDestination.readAsStringSync(), 'some string');
-
-      fileContent.copyToFile(fileDestination);
-      expect(fileDestination.readAsStringSync(), 'hello, world');
-    });
-
     test('bytes', () {
       final DevFSByteContent content = DevFSByteContent(<int>[4, 5, 6]);
       expect(content.bytes, orderedEquals(<int>[4, 5, 6]));
@@ -65,7 +41,6 @@
       expect(content.isModified, isTrue);
       expect(content.isModified, isFalse);
     });
-
     test('string', () {
       final DevFSStringContent content = DevFSStringContent('some string');
       expect(content.string, 'some string');
@@ -83,9 +58,7 @@
       expect(content.isModified, isTrue);
       expect(content.isModified, isFalse);
     });
-
     testUsingContext('file', () async {
-      final String filePath = fs.path.join('lib', 'foo.txt');
       final File file = fs.file(filePath);
       final DevFSFileContent content = DevFSFileContent(file);
       expect(content.isModified, isFalse);
@@ -100,9 +73,10 @@
       expect(content.isModifiedAfter(null), isTrue);
 
       file.writeAsBytesSync(<int>[2, 3, 4], flush: true);
+      expect(content.fileDependencies, <String>[filePath]);
       expect(content.isModified, isTrue);
       expect(content.isModified, isFalse);
-      expect(content.contentsAsBytes(), <int>[2, 3, 4]);
+      expect(await content.contentsAsBytes(), <int>[2, 3, 4]);
       updateFileModificationTime(file.path, fiveSecondsAgo, 0);
       expect(content.isModified, isFalse);
       expect(content.isModified, isFalse);
@@ -113,56 +87,36 @@
       expect(content.isModified, isFalse);
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
-    }, skip: platform.isWindows); // Still flaky, but only on CI :(
+    }, skip: Platform.isWindows); // TODO(jonahwilliams): fix or disable this functionality.
   });
 
   group('devfs remote', () {
-    DevFS devFS;
-    MockResidentCompiler residentCompiler;
-    MockDevFSOperations mockDevFSOperations;
-    int created;
-    int destroyed;
-    List<String> writtenFiles;
-    bool exists;
+    MockVMService vmService;
+    final MockResidentCompiler residentCompiler = MockResidentCompiler();
 
-    setUp(() async {
-      mockDevFSOperations = MockDevFSOperations();
-      devFS = DevFS.operations(mockDevFSOperations, 'test', fs.currentDirectory);
-      residentCompiler = MockResidentCompiler();
-      created = 0;
-      destroyed = 0;
-      exists = false;
-      writtenFiles = <String>[];
-      when(mockDevFSOperations.create('test')).thenAnswer((Invocation invocation) async {
-        if (exists) {
-          throw rpc.RpcException(1001, 'already exists');
-        }
-        exists = true;
-        created += 1;
-        return Uri.parse(InternetAddress.loopbackIPv4.toString());
-      });
-      when(mockDevFSOperations.destroy('test')).thenAnswer((Invocation invocation) async {
-        exists = false;
-        destroyed += 1;
-      });
-      when(mockDevFSOperations.write(any)).thenAnswer((Invocation invocation) async {
-        final Map<Uri, DevFSContent> entries = invocation.positionalArguments.first;
-        writtenFiles.addAll(entries.keys.map((Uri uri) => uri.toFilePath()));
-      });
+    setUpAll(() async {
+      tempDir = _newTempDir(fs);
+      basePath = tempDir.path;
+      vmService = MockVMService();
+      await vmService.setUp();
+    });
+    tearDownAll(() async {
+      await vmService.tearDown();
+      _cleanupTempDirs();
     });
 
     testUsingContext('create dev file system', () async {
       // simulate workspace
-      final String filePath = fs.path.join('lib', 'foo.txt');
-      final File file = fs.file(filePath);
+      final File file = fs.file(fs.path.join(basePath, filePath));
       await file.parent.create(recursive: true);
       file.writeAsBytesSync(<int>[1, 2, 3]);
 
       // simulate package
       await _createPackage(fs, 'somepkg', 'somefile.txt');
-      await devFS.create();
 
-      expect(created, 1);
+      devFS = DevFS(vmService, 'test', tempDir);
+      await devFS.create();
+      vmService.expectMessages(<String>['create test']);
       expect(devFS.assetPathsToEvict, isEmpty);
 
       final UpdateFSReport report = await devFS.update(
@@ -172,8 +126,9 @@
         trackWidgetCreation: false,
         invalidatedFiles: <Uri>[],
       );
-
-      expect(writtenFiles.single, contains('foo.txt.dill'));
+      vmService.expectMessages(<String>[
+        'writeFile test lib/foo.txt.dill',
+      ]);
       expect(devFS.assetPathsToEvict, isEmpty);
       expect(report.syncedBytes, 22);
       expect(report.success, true);
@@ -182,8 +137,9 @@
     });
 
     testUsingContext('delete dev file system', () async {
+      expect(vmService.messages, isEmpty, reason: 'prior test timeout');
       await devFS.destroy();
-      expect(destroyed, 1);
+      vmService.expectMessages(<String>['destroy test']);
       expect(devFS.assetPathsToEvict, isEmpty);
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
@@ -191,27 +147,26 @@
 
     testUsingContext('cleanup preexisting file system', () async {
       // simulate workspace
-      final String filePath = fs.path.join('lib', 'foo.txt');
-      final File file = fs.file(filePath);
+      final File file = fs.file(fs.path.join(basePath, filePath));
       await file.parent.create(recursive: true);
       file.writeAsBytesSync(<int>[1, 2, 3]);
 
       // simulate package
       await _createPackage(fs, 'somepkg', 'somefile.txt');
 
+      devFS = DevFS(vmService, 'test', tempDir);
       await devFS.create();
-      expect(created, 1);
+      vmService.expectMessages(<String>['create test']);
       expect(devFS.assetPathsToEvict, isEmpty);
 
       // Try to create again.
       await devFS.create();
-      expect(created, 2);
-      expect(destroyed, 1);
+      vmService.expectMessages(<String>['create test', 'destroy test', 'create test']);
       expect(devFS.assetPathsToEvict, isEmpty);
 
       // Really destroy.
       await devFS.destroy();
-      expect(destroyed, 2);
+      vmService.expectMessages(<String>['destroy test']);
       expect(devFS.assetPathsToEvict, isEmpty);
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
@@ -219,20 +174,113 @@
   });
 }
 
-class MockVMService extends Mock implements VMService {}
+class MockVMService extends BasicMock implements VMService {
+  MockVMService() {
+    _vm = MockVM(this);
+  }
 
-class MockDevFSOperations extends Mock implements DevFSOperations {}
+  Uri _httpAddress;
+  HttpServer _server;
+  MockVM _vm;
 
-class MockPlatform extends Mock implements Platform {}
+  @override
+  Uri get httpAddress => _httpAddress;
 
+  @override
+  VM get vm => _vm;
+
+  Future<void> setUp() async {
+    try {
+      _server = await HttpServer.bind(InternetAddress.loopbackIPv6, 0);
+      _httpAddress = Uri.parse('http://[::1]:${_server.port}');
+    } on SocketException {
+      // Fall back to IPv4 if the host doesn't support binding to IPv6 localhost
+      _server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
+      _httpAddress = Uri.parse('http://127.0.0.1:${_server.port}');
+    }
+    _server.listen((HttpRequest request) {
+      final String fsName = request.headers.value('dev_fs_name');
+      final String devicePath = utf8.decode(base64.decode(request.headers.value('dev_fs_uri_b64')));
+      messages.add('writeFile $fsName $devicePath');
+      request.drain<List<int>>().then<void>((List<int> value) {
+        request.response
+          ..write('Got it')
+          ..close();
+      });
+    });
+  }
+
+  Future<void> tearDown() async {
+    await _server?.close();
+  }
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class MockVM implements VM {
+  MockVM(this._service);
+
+  final MockVMService _service;
+  final Uri _baseUri = Uri.parse('file:///tmp/devfs/test');
+  bool _devFSExists = false;
+
+  static const int kFileSystemAlreadyExists = 1001;
+
+  @override
+  Future<Map<String, dynamic>> createDevFS(String fsName) async {
+    _service.messages.add('create $fsName');
+    if (_devFSExists) {
+      throw rpc.RpcException(kFileSystemAlreadyExists, 'File system already exists');
+    }
+    _devFSExists = true;
+    return <String, dynamic>{'uri': '$_baseUri'};
+  }
+
+  @override
+  Future<Map<String, dynamic>> deleteDevFS(String fsName) async {
+    _service.messages.add('destroy $fsName');
+    _devFSExists = false;
+    return <String, dynamic>{'type': 'Success'};
+  }
+
+  @override
+  Future<Map<String, dynamic>> invokeRpcRaw(
+    String method, {
+    Map<String, dynamic> params = const <String, dynamic>{},
+    Duration timeout,
+    bool timeoutFatal = true,
+  }) async {
+    _service.messages.add('$method $params');
+    return <String, dynamic>{'success': true};
+  }
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+final List<Directory> _tempDirs = <Directory>[];
 final Map <String, Uri> _packages = <String, Uri>{};
 
+Directory _newTempDir(FileSystem fs) {
+  final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_devfs${_tempDirs.length}_test.');
+  _tempDirs.add(tempDir);
+  return tempDir;
+}
+
+void _cleanupTempDirs() {
+  while (_tempDirs.isNotEmpty)
+    tryToDelete(_tempDirs.removeLast());
+}
 
 Future<void> _createPackage(FileSystem fs, String pkgName, String pkgFileName, { bool doubleSlash = false }) async {
-  String pkgFilePath = fs.path.join(pkgName, 'lib', pkgFileName);
+  final Directory pkgTempDir = _newTempDir(fs);
+  String pkgFilePath = fs.path.join(pkgTempDir.path, pkgName, 'lib', pkgFileName);
   if (doubleSlash) {
     // Force two separators into the path.
-    pkgFilePath = fs.path.join(pkgName, 'lib', pkgFileName);
+    final String doubleSlash = fs.path.separator + fs.path.separator;
+    pkgFilePath = pkgTempDir.path + doubleSlash + fs.path.join(pkgName, 'lib', pkgFileName);
   }
   final File pkgFile = fs.file(pkgFilePath);
   await pkgFile.parent.create(recursive: true);
@@ -242,5 +290,6 @@
   _packages.forEach((String pkgName, Uri pkgUri) {
     sb.writeln('$pkgName:$pkgUri');
   });
-  fs.file('.packages').writeAsStringSync(sb.toString());
+  fs.file(fs.path.join(_tempDirs[0].path, '.packages')).writeAsStringSync(sb.toString());
 }
+
