Browse Source

Use UnitTestApplication in some more places.

Also removed service registration from some tests that now don't require
it.
Steven Kirk 9 years ago
parent
commit
9a0df79ec5

+ 27 - 47
tests/Perspex.Controls.UnitTests/ContentControlTests.cs

@@ -1,18 +1,14 @@
 // Copyright (c) The Perspex Project. All rights reserved.
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
-using System;
 using System.Collections.Specialized;
 using System.Linq;
 using Moq;
 using Perspex.Controls.Presenters;
 using Perspex.Controls.Templates;
 using Perspex.LogicalTree;
-using Perspex.Platform;
 using Perspex.Styling;
 using Perspex.VisualTree;
-using Ploeh.AutoFixture;
-using Ploeh.AutoFixture.AutoMoq;
 using Xunit;
 
 namespace Perspex.Controls.UnitTests
@@ -22,44 +18,38 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Template_Should_Be_Instantiated()
         {
-            using (var ctx = RegisterServices())
-            {
-                var target = new ContentControl();
-                target.Content = "Foo";
-                target.Template = GetTemplate();
-                target.ApplyTemplate();
-                ((ContentPresenter)target.Presenter).UpdateChild();
-
-                var child = ((IVisual)target).VisualChildren.Single();
-                Assert.IsType<Border>(child);
-                child = child.VisualChildren.Single();
-                Assert.IsType<ContentPresenter>(child);
-                child = child.VisualChildren.Single();
-                Assert.IsType<TextBlock>(child);
-            }
+            var target = new ContentControl();
+            target.Content = "Foo";
+            target.Template = GetTemplate();
+            target.ApplyTemplate();
+            ((ContentPresenter)target.Presenter).UpdateChild();
+
+            var child = ((IVisual)target).VisualChildren.Single();
+            Assert.IsType<Border>(child);
+            child = child.VisualChildren.Single();
+            Assert.IsType<ContentPresenter>(child);
+            child = child.VisualChildren.Single();
+            Assert.IsType<TextBlock>(child);
         }
 
         [Fact]
         public void Templated_Children_Should_Be_Styled()
         {
-            using (var ctx = RegisterServices())
-            {
-                var root = new TestRoot();
-                var target = new ContentControl();
-                var styler = new Mock<IStyler>();
-
-                PerspexLocator.CurrentMutable.Bind<IStyler>().ToConstant(styler.Object);
-                target.Content = "Foo";
-                target.Template = GetTemplate();
-                root.Child = target;
-
-                target.ApplyTemplate();
-
-                styler.Verify(x => x.ApplyStyles(It.IsAny<ContentControl>()), Times.Once());
-                styler.Verify(x => x.ApplyStyles(It.IsAny<Border>()), Times.Once());
-                styler.Verify(x => x.ApplyStyles(It.IsAny<ContentPresenter>()), Times.Once());
-                styler.Verify(x => x.ApplyStyles(It.IsAny<TextBlock>()), Times.Once());
-            }
+            var root = new TestRoot();
+            var target = new ContentControl();
+            var styler = new Mock<IStyler>();
+
+            PerspexLocator.CurrentMutable.Bind<IStyler>().ToConstant(styler.Object);
+            target.Content = "Foo";
+            target.Template = GetTemplate();
+            root.Child = target;
+
+            target.ApplyTemplate();
+
+            styler.Verify(x => x.ApplyStyles(It.IsAny<ContentControl>()), Times.Once());
+            styler.Verify(x => x.ApplyStyles(It.IsAny<Border>()), Times.Once());
+            styler.Verify(x => x.ApplyStyles(It.IsAny<ContentPresenter>()), Times.Once());
+            styler.Verify(x => x.ApplyStyles(It.IsAny<TextBlock>()), Times.Once());
         }
 
         [Fact]
@@ -261,15 +251,5 @@ namespace Perspex.Controls.UnitTests
                 };
             });
         }
-
-        private IDisposable RegisterServices()
-        {
-            var result = PerspexLocator.EnterScope();
-            var fixture = new Fixture().Customize(new AutoMoqCustomization());
-            var renderInterface = fixture.Create<IPlatformRenderInterface>();
-            PerspexLocator.CurrentMutable
-                .Bind<IPlatformRenderInterface>().ToConstant(renderInterface);
-            return result;
-        }
     }
 }

+ 0 - 10
tests/Perspex.Controls.UnitTests/DropDownTests.cs

@@ -41,15 +41,5 @@ namespace Perspex.Controls.UnitTests
                 };
             });
         }
-
-        private IDisposable RegisterServices()
-        {
-            var result = PerspexLocator.EnterScope();
-            var fixture = new Fixture().Customize(new AutoMoqCustomization());
-            var renderInterface = fixture.Create<IPlatformRenderInterface>();
-            PerspexLocator.CurrentMutable.Bind<IPlatformRenderInterface>().ToConstant(renderInterface);
-
-            return result;
-        }
     }
 }

+ 3 - 5
tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs

@@ -10,6 +10,7 @@ using Perspex.Controls.Primitives;
 using Perspex.Controls.Templates;
 using Perspex.LogicalTree;
 using Perspex.Styling;
+using Perspex.UnitTests;
 using Perspex.VisualTree;
 using Xunit;
 
@@ -176,12 +177,8 @@ namespace Perspex.Controls.UnitTests.Primitives
         [Fact]
         public void Templated_Children_Should_Be_Styled()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.MockStyler))
             {
-                var styler = new Mock<IStyler>();
-
-                PerspexLocator.CurrentMutable.Bind<IStyler>().ToConstant(styler.Object);
-
                 TestTemplatedControl target;
 
                 var root = new TestRoot
@@ -205,6 +202,7 @@ namespace Perspex.Controls.UnitTests.Primitives
 
                 target.ApplyTemplate();
 
+                var styler = Mock.Get(UnitTestApplication.Current.Services.Styler);
                 styler.Verify(x => x.ApplyStyles(It.IsAny<TestTemplatedControl>()), Times.Once());
                 styler.Verify(x => x.ApplyStyles(It.IsAny<StackPanel>()), Times.Once());
                 styler.Verify(x => x.ApplyStyles(It.IsAny<TextBlock>()), Times.Once());

+ 2 - 3
tests/Perspex.Controls.UnitTests/TabControlTests.cs

@@ -9,6 +9,7 @@ using Perspex.Controls.Primitives;
 using Perspex.Controls.Templates;
 using Perspex.LogicalTree;
 using Perspex.Styling;
+using Perspex.UnitTests;
 using Xunit;
 
 namespace Perspex.Controls.UnitTests
@@ -130,10 +131,8 @@ namespace Perspex.Controls.UnitTests
 
             var template = new FuncControlTemplate<TabItem>(x => new Decorator());
 
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.RealStyler))
             {
-                PerspexLocator.CurrentMutable.Bind<IStyler>().ToConstant(new Styler());
-
                 var root = new TestRoot
                 {
                     Styles = new Styles

+ 21 - 45
tests/Perspex.Controls.UnitTests/TopLevelTests.cs

@@ -13,6 +13,7 @@ using Perspex.Layout;
 using Perspex.Platform;
 using Perspex.Rendering;
 using Perspex.Styling;
+using Perspex.UnitTests;
 using Ploeh.AutoFixture;
 using Ploeh.AutoFixture.AutoMoq;
 using Xunit;
@@ -24,10 +25,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void ClientSize_Should_Be_Set_On_Construction()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
 
@@ -40,10 +39,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Width_Should_Not_Be_Set_On_Construction()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
 
@@ -56,10 +53,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Height_Should_Not_Be_Set_On_Construction()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
 
@@ -72,10 +67,10 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Layout_Pass_Should_Not_Be_Automatically_Scheduled()
         {
-            using (PerspexLocator.EnterScope())
-            {
-                RegisterServices();
+            var services = TestServices.StyledWindow.With(layoutManager: Mock.Of<ILayoutManager>());
 
+            using (UnitTestApplication.Start(services))
+            {
                 var impl = new Mock<ITopLevelImpl>();
                 var target = new TestTopLevel(impl.Object);
 
@@ -88,11 +83,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Bounds_Should_Be_Set_After_Layout_Pass()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-                PerspexLocator.CurrentMutable.Bind<ILayoutManager>().ToConstant(new LayoutManager());
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.SetupProperty(x => x.ClientSize);
                 impl.SetupProperty(x => x.Resized);
@@ -116,11 +108,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Impl_ClientSize_Should_Be_Set_After_Layout_Pass()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-                PerspexLocator.CurrentMutable.Bind<ILayoutManager>().ToConstant(new LayoutManager());
-
                 var impl = new Mock<ITopLevelImpl>();
 
                 var target = new TestTopLevel(impl.Object)
@@ -142,10 +131,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Width_And_Height_Should_Not_Be_Set_After_Layout_Pass()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
 
@@ -160,10 +147,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Width_And_Height_Should_Be_Set_After_Window_Resize_Notification()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.SetupAllProperties();
                 impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
@@ -180,10 +165,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Activate_Should_Call_Impl_Activate()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 var target = new TestTopLevel(impl.Object);
 
@@ -196,10 +179,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Impl_Activate_Should_Call_Raise_Activated_Event()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.SetupAllProperties();
 
@@ -216,10 +197,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Impl_Close_Should_Call_Raise_Closed_Event()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.SetupAllProperties();
 
@@ -236,10 +215,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Impl_Deactivate_Should_Call_Raise_Activated_Event()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.SetupAllProperties();
 
@@ -256,12 +233,14 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Impl_Input_Should_Pass_Input_To_InputManager()
         {
-            using (PerspexLocator.EnterScope())
-            {
-                RegisterServices();
+            var inputManagerMock = new Mock<IInputManager>();
+            var services = TestServices.StyledWindow.With(inputManager: inputManagerMock.Object);
 
+            using (UnitTestApplication.Start(services))
+            {
                 var impl = new Mock<ITopLevelImpl>();
                 impl.SetupAllProperties();
+
                 var target = new TestTopLevel(impl.Object);
 
                 var input = new RawKeyEventArgs(
@@ -271,7 +250,6 @@ namespace Perspex.Controls.UnitTests
                     Key.A, InputModifiers.None);
                 impl.Object.Input(input);
 
-                var inputManagerMock = Mock.Get(InputManager.Instance);
                 inputManagerMock.Verify(x => x.Process(input));
             }
         }
@@ -279,10 +257,8 @@ namespace Perspex.Controls.UnitTests
         [Fact]
         public void Adding_Top_Level_As_Child_Should_Throw_Exception()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
-                RegisterServices();
-
                 var impl = new Mock<ITopLevelImpl>();
                 impl.SetupAllProperties();
                 var target = new TestTopLevel(impl.Object);

+ 4 - 20
tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs

@@ -3,13 +3,11 @@
 
 using System.Linq;
 using System.Reactive.Linq;
-using Moq;
 using Perspex.Controls;
-using Perspex.Controls.Primitives;
 using Perspex.Data;
 using Perspex.Markup.Xaml.Data;
-using Perspex.Platform;
 using Perspex.Styling;
+using Perspex.UnitTests;
 using Xunit;
 
 namespace Perspex.Markup.Xaml.UnitTests
@@ -19,12 +17,8 @@ namespace Perspex.Markup.Xaml.UnitTests
         [Fact]
         public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.MockPlatformWrapper))
             {
-                PerspexLocator.CurrentMutable
-                    .Bind<IPclPlatformWrapper>()
-                    .ToConstant(Mock.Of<IPclPlatformWrapper>());
-
                 var xaml = "<Style xmlns='https://github.com/perspex'><Setter Value='{Binding}'/></Style>";
                 var loader = new PerspexXamlLoader();
                 var style = (Style)loader.Load(xaml);
@@ -37,13 +31,8 @@ namespace Perspex.Markup.Xaml.UnitTests
         [Fact]
         public void Setter_With_TwoWay_Binding_Should_Update_Source()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.MockThreadingInterface))
             {
-                PerspexLocator.CurrentMutable
-                    .Bind<IPlatformThreadingInterface>()
-                    .ToConstant(Mock.Of<IPlatformThreadingInterface>(x => 
-                        x.CurrentThreadIsLoopThread == true));
-
                 var data = new Data
                 {
                     Foo = "foo",
@@ -75,13 +64,8 @@ namespace Perspex.Markup.Xaml.UnitTests
         [Fact]
         public void Setter_With_TwoWay_Binding_And_Activator_Should_Update_Source()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.MockThreadingInterface))
             {
-                PerspexLocator.CurrentMutable
-                    .Bind<IPlatformThreadingInterface>()
-                    .ToConstant(Mock.Of<IPlatformThreadingInterface>(x =>
-                        x.CurrentThreadIsLoopThread == true));
-
                 var data = new Data
                 {
                     Foo = "foo",

+ 2 - 7
tests/Perspex.Markup.Xaml.UnitTests/Templates/TreeDataTemplateTests.cs

@@ -2,11 +2,10 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 using System.Linq;
-using Moq;
 using Perspex.Controls.Templates;
 using Perspex.Markup.Xaml.Data;
 using Perspex.Markup.Xaml.Templates;
-using Perspex.Platform;
+using Perspex.UnitTests;
 using Xunit;
 
 namespace Perspex.Markup.Xaml.UnitTests
@@ -16,12 +15,8 @@ namespace Perspex.Markup.Xaml.UnitTests
         [Fact]
         public void Binding_Should_Be_Assigned_To_ItemsSource_Instead_Of_Bound()
         {
-            using (PerspexLocator.EnterScope())
+            using (UnitTestApplication.Start(TestServices.MockPlatformWrapper))
             {
-                PerspexLocator.CurrentMutable
-                    .Bind<IPclPlatformWrapper>()
-                    .ToConstant(Mock.Of<IPclPlatformWrapper>());
-
                 var xaml = "<DataTemplates xmlns='https://github.com/perspex'><TreeDataTemplate ItemsSource='{Binding}'/></DataTemplates>";
                 var loader = new PerspexXamlLoader();
                 var templates = (DataTemplates)loader.Load(xaml);

+ 88 - 22
tests/Perspex.UnitTests/TestServices.cs

@@ -2,7 +2,9 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 using System;
+using System.Reflection;
 using Moq;
+using Perspex.Input;
 using Perspex.Layout;
 using Perspex.Platform;
 using Perspex.Shared.PlatformSupport;
@@ -17,28 +19,92 @@ namespace Perspex.UnitTests
     {
         private static IFixture s_fixture = new Fixture().Customize(new AutoMoqCustomization());
 
-        public static readonly TestServices StyledWindow = new TestServices
+        public static readonly TestServices StyledWindow = new TestServices(
+            assetLoader: new AssetLoader(),
+            layoutManager: new LayoutManager(),
+            platformWrapper: new PclPlatformWrapper(),
+            renderInterface: s_fixture.Create<IPlatformRenderInterface>(),
+            standardCursorFactory: Mock.Of<IStandardCursorFactory>(),
+            styler: new Styler(),
+            theme: () => new DefaultTheme(),
+            threadingInterface: Mock.Of<IPlatformThreadingInterface>(x => x.CurrentThreadIsLoopThread == true),
+            windowingPlatform: new MockWindowingPlatform());
+
+        public static readonly TestServices MockPlatformWrapper = new TestServices(
+            platformWrapper: Mock.Of<IPclPlatformWrapper>());
+
+        public static readonly TestServices MockStyler = new TestServices(
+            styler: Mock.Of<IStyler>());
+
+        public static readonly TestServices MockThreadingInterface = new TestServices(
+            threadingInterface: Mock.Of<IPlatformThreadingInterface>(x => x.CurrentThreadIsLoopThread == true));
+
+        public static readonly TestServices RealStyler = new TestServices(
+            styler: new Styler());
+
+        public TestServices(
+            IAssetLoader assetLoader = null,
+            IInputManager inputManager = null,
+            ILayoutManager layoutManager = null,
+            IPclPlatformWrapper platformWrapper = null,
+            IPlatformRenderInterface renderInterface = null,
+            IStandardCursorFactory standardCursorFactory = null,
+            IStyler styler = null,
+            Func<Styles> theme = null,
+            IPlatformThreadingInterface threadingInterface = null,
+            IWindowImpl windowImpl = null,
+            IWindowingPlatform windowingPlatform = null)
+        {
+            AssetLoader = assetLoader;
+            InputManager = inputManager;
+            LayoutManager = layoutManager;
+            PlatformWrapper = platformWrapper;
+            RenderInterface = renderInterface;
+            StandardCursorFactory = standardCursorFactory;
+            Styler = styler;
+            Theme = theme;
+            ThreadingInterface = threadingInterface;
+            WindowImpl = windowImpl;
+            WindowingPlatform = windowingPlatform;
+        }
+
+        public IAssetLoader AssetLoader { get; }
+        public IInputManager InputManager { get; }
+        public ILayoutManager LayoutManager { get; }
+        public IPclPlatformWrapper PlatformWrapper { get; }
+        public IPlatformRenderInterface RenderInterface { get; }
+        public IStandardCursorFactory StandardCursorFactory { get; }
+        public IStyler Styler { get; }
+        public Func<Styles> Theme { get; }
+        public IPlatformThreadingInterface ThreadingInterface { get; }
+        public IWindowImpl WindowImpl { get; }
+        public IWindowingPlatform WindowingPlatform { get; }
+
+        public TestServices With(
+            IAssetLoader assetLoader = null,
+            IInputManager inputManager = null,
+            ILayoutManager layoutManager = null,
+            IPclPlatformWrapper platformWrapper = null,
+            IPlatformRenderInterface renderInterface = null,
+            IStandardCursorFactory standardCursorFactory = null,
+            IStyler styler = null,
+            Func<Styles> theme = null,
+            IPlatformThreadingInterface threadingInterface = null,
+            IWindowImpl windowImpl = null,
+            IWindowingPlatform windowingPlatform = null)
         {
-            AssetLoader = new AssetLoader(),
-            LayoutManager = new LayoutManager(),
-            PlatformWrapper = new PclPlatformWrapper(),
-            RenderInterface = s_fixture.Create<IPlatformRenderInterface>(),
-            StandardCursorFactory = Mock.Of<IStandardCursorFactory>(),
-            Styler = new Styler(),
-            Theme = () => new DefaultTheme(),
-            ThreadingInterface = Mock.Of<IPlatformThreadingInterface>(x => x.CurrentThreadIsLoopThread == true),
-            WindowingPlatform = new MockWindowingPlatform(),
-        };
-
-        public IAssetLoader AssetLoader { get; set; }
-        public ILayoutManager LayoutManager { get; set; }
-        public IPclPlatformWrapper PlatformWrapper { get; set; }
-        public IPlatformRenderInterface RenderInterface { get; set; }
-        public IStandardCursorFactory StandardCursorFactory { get; set; }
-        public IStyler Styler { get; set; }
-        public Func<Styles> Theme { get; set; }
-        public IPlatformThreadingInterface ThreadingInterface { get; set; }
-        public IWindowImpl WindowImpl { get; set; }
-        public IWindowingPlatform WindowingPlatform { get; set; }
+            return new TestServices(
+                assetLoader: assetLoader ?? AssetLoader,
+                inputManager: inputManager ?? InputManager,
+                layoutManager: layoutManager ?? LayoutManager,
+                platformWrapper: platformWrapper ?? PlatformWrapper,
+                renderInterface: renderInterface ?? RenderInterface,
+                standardCursorFactory: standardCursorFactory ?? StandardCursorFactory,
+                styler: styler ?? Styler,
+                theme: theme ?? Theme,
+                threadingInterface: threadingInterface ?? ThreadingInterface,
+                windowImpl: windowImpl ?? WindowImpl,
+                windowingPlatform: windowingPlatform ?? WindowingPlatform);
+        }
     }
 }

+ 6 - 2
tests/Perspex.UnitTests/UnitTestApplication.cs

@@ -2,6 +2,7 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 using System;
+using Perspex.Input;
 using Perspex.Layout;
 using Perspex.Platform;
 using Perspex.Styling;
@@ -12,11 +13,13 @@ namespace Perspex.UnitTests
     {
         public UnitTestApplication(TestServices services)
         {
-            Services = services;
+            Services = services ?? new TestServices();
             RegisterServices();
-            Styles = services.Theme();
+            Styles = Services.Theme?.Invoke();
         }
 
+        public static new UnitTestApplication Current => (UnitTestApplication)Application.Current;
+
         public TestServices Services { get; }
 
         public static IDisposable Start(TestServices services = null)
@@ -31,6 +34,7 @@ namespace Perspex.UnitTests
             PerspexLocator.CurrentMutable
                 .Bind<IAssetLoader>().ToConstant(Services.AssetLoader)
                 .BindToSelf<IGlobalStyles>(this)
+                .Bind<IInputManager>().ToConstant(Services.InputManager)
                 .Bind<ILayoutManager>().ToConstant(Services.LayoutManager)
                 .Bind<IPclPlatformWrapper>().ToConstant(Services.PlatformWrapper)
                 .Bind<IPlatformRenderInterface>().ToConstant(Services.RenderInterface)