Skip to content

Commit

Permalink
NR Migrate unit tests to xunit; add unit test project for application…
Browse files Browse the repository at this point in the history
…s layer; minor code improvements
  • Loading branch information
jbe2277 committed Dec 8, 2023
1 parent 866e525 commit 912bfa1
Show file tree
Hide file tree
Showing 29 changed files with 393 additions and 155 deletions.
4 changes: 2 additions & 2 deletions src/NewsReader/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4" />
</ItemGroup>
</When>
<Otherwise>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Test.NewsReader.Applications.Views;
using Waf.NewsReader.Applications.ViewModels;
using Xunit;

namespace Test.NewsReader.Applications.Controllers;

public class AppControllerTest : TestBase
{
[Fact]
public async Task OpenSettingsView()
{
StartApp();
await Task.Delay(50); // TODO: Waiting for some time is not the best way to solve this
var feed = Shell.View.GetCurrentView<MockFeedView, FeedViewModel>();
Assert.Equal(FeedsController.FeedManager.Feeds.Single(), feed.ViewModel.Feed);

Shell.ViewModel.SelectedFooterMenu = Shell.ViewModel.FooterMenu[1];
var settings = Shell.View.GetCurrentView<MockSettingsView, SettingsViewModel>();
Assert.NotNull(settings.View);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Autofac;
using System.Waf.Applications.Services;
using System.Waf.UnitTesting.Mocks;
using Test.NewsReader.Applications.Services;
using Test.NewsReader.Applications.Views;
using Waf.NewsReader.Applications.Services;
using Waf.NewsReader.Applications.Views;

namespace Test.NewsReader.Applications;

public class MockPresentationModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MockAppInfoService>().AsSelf().As<IAppInfoService>().SingleInstance();
builder.RegisterType<MockDataService>().AsSelf().As<IDataService>().SingleInstance();
builder.RegisterType<MockLauncherService>().AsSelf().As<ILauncherService>().SingleInstance();
builder.RegisterType<MockMessageService>().AsSelf().As<IMessageService>().SingleInstance();
builder.RegisterType<MockNetworkInfoService>().AsSelf().As<INetworkInfoService>().SingleInstance();
builder.RegisterType<MockSettingsService>().AsSelf().As<ISettingsService>().SingleInstance();
builder.RegisterType<MockSyndicationService>().AsSelf().As<ISyndicationService>().SingleInstance();
builder.RegisterType<MockWebStorageService>().AsSelf().As<IWebStorageService>().SingleInstance();

builder.RegisterType<MockFeedView>().AsSelf().As<IFeedView>().SingleInstance();
builder.RegisterType<MockSettingsView>().AsSelf().As<ISettingsView>().SingleInstance();
builder.RegisterType<MockShellView>().AsSelf().As<IShellView>().SingleInstance();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Test.NewsReader.Applications</RootNamespace>
<AssemblyName>Test.NewsReader.Applications</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Waf.UnitTesting.Core" Version="7.0.1-alpha.0.80" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NewsReader.Applications\NewsReader.Applications.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Waf.NewsReader.Applications.Services;

namespace Test.NewsReader.Applications.Services;

internal class MockAppInfoService : IAppInfoService
{
public string AppName => "TestApp";

public string VersionString => "1.2.3";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Waf.NewsReader.Applications.Services;

namespace Test.NewsReader.Applications.Services;

public class MockDataService : IDataService
{
public string GetHash()
{
throw new NotImplementedException();
}

public Stream GetReadStream()
{
throw new NotImplementedException();
}

public T? Load<T>(Stream? dataStream = null) where T : class
{
throw new NotImplementedException();
}

public void Save(object data)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Waf.NewsReader.Applications.Services;

namespace Test.NewsReader.Applications.Services;
public class MockLauncherService : ILauncherService
{
public Task LaunchBrowser(Uri uri) => throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Waf.NewsReader.Applications.Services;

namespace Test.NewsReader.Applications.Services;

public class MockMessageService : IMessageService
{
public Task ShowMessage(string message)
{
throw new NotImplementedException();
}

public Task<bool> ShowYesNoQuestion(string message)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Waf.NewsReader.Applications.Services;

namespace Test.NewsReader.Applications.Services;

public class MockNetworkInfoService : Model, INetworkInfoService
{
private bool internetAccess;

public bool InternetAccess { get => internetAccess; set => SetProperty(ref internetAccess, value); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Waf.NewsReader.Applications.Services;

namespace Test.NewsReader.Applications.Services;

public class MockSyndicationService : ISyndicationService
{
public Task<FeedDto> RetrieveFeed(Uri uri)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Waf.NewsReader.Applications.Services;

namespace Test.NewsReader.Applications.Services;

public class MockWebStorageService : Model, IWebStorageService
{
private UserAccount? currentAccount;

public UserAccount? CurrentAccount { get => currentAccount; set => SetProperty(ref currentAccount, value); }

public Task<(Stream? stream, string? cTag)> DownloadFile(string? cTag)
{
throw new NotImplementedException();
}

public Task SignIn()
{
throw new NotImplementedException();
}

public Task SignOut()
{
throw new NotImplementedException();
}

public Task<bool> TrySilentSignIn() => Task.FromResult(false);

public Task<string?> UploadFile(Stream source)
{
throw new NotImplementedException();
}
}
42 changes: 42 additions & 0 deletions src/NewsReader/NewsReader.Applications.Test/TestBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Autofac;
using System.Waf.Applications;
using Waf.NewsReader.Applications.ViewModels;
using Waf.NewsReader.Applications;
using Waf.NewsReader.Applications.Controllers;
using Test.NewsReader.Applications.Views;

namespace Test.NewsReader.Applications;

public record ViewPair<TView, TViewModel>(TView View) where TView : IView where TViewModel : IViewModelCore
{
public TViewModel ViewModel => (TViewModel)View.DataContext!;
}

public abstract class TestBase
{
protected TestBase()
{
var builder = new ContainerBuilder();
builder.RegisterModule(new ApplicationsModule());
builder.RegisterModule(new MockPresentationModule());
Container = builder.Build();
}

public Autofac.IContainer Container { get; }

internal AppController AppController { get; private set; } = null!;
internal FeedsController FeedsController { get; private set; } = null!;
internal SettingsController SettingsController { get; private set; } = null!;
public ViewPair<MockShellView, ShellViewModel> Shell { get; private set; } = null!;

public T Resolve<T>() where T : notnull => Container.Resolve<T>();

public void StartApp()
{
AppController = Resolve<AppController>();
FeedsController = Resolve<FeedsController>();
SettingsController = Resolve<SettingsController>();
AppController.Start();
Shell = new((MockShellView)AppController.MainView);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Waf.UnitTesting.Mocks;
using Waf.NewsReader.Applications.Views;

namespace Test.NewsReader.Applications.Views;

public class MockFeedView : MockView, IFeedView
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Waf.UnitTesting.Mocks;
using Waf.NewsReader.Applications.Views;

namespace Test.NewsReader.Applications.Views;

public class MockSettingsView : MockView, ISettingsView
{
}
31 changes: 31 additions & 0 deletions src/NewsReader/NewsReader.Applications.Test/Views/MockShellView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Waf.Applications;
using System.Waf.UnitTesting.Mocks;
using Waf.NewsReader.Applications.ViewModels;
using Waf.NewsReader.Applications.Views;

namespace Test.NewsReader.Applications.Views;

public class MockShellView : MockView, IShellView
{
private readonly Stack<object> pageStack = new();
private object currentPage = null!;

public object CurrentPage
{
get => currentPage;
private set
{
currentPage = value;
((ShellViewModel)DataContext!).InternalSetCurrentPage(CurrentPage);
}
}

public Task PushAsync(object page) { pageStack.Push(page); CurrentPage = page; return Task.CompletedTask; }

public Task PopAsync() { CurrentPage = pageStack.Pop(); return Task.CompletedTask; }

public void CloseFlyout() { }

public ViewPair<TView, TViewModel> GetCurrentView<TView, TViewModel>() where TView : IView where TViewModel : IViewModelCore => new((TView)CurrentPage!);
}

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="Test.NewsReader.Applications" />

<Compile Update="Properties\Resources.Designer.cs" DesignTime="True" AutoGen="True" DependentUpon="Resources.resx" />
<EmbeddedResource Update="Properties\Resources.resx" Generator="ResXFileCodeGenerator" LastGenOutput="Resources.Designer.cs" />
</ItemGroup>
Expand Down
42 changes: 20 additions & 22 deletions src/NewsReader/NewsReader.Domain.Test/FeedItemTest.cs
Original file line number Diff line number Diff line change
@@ -1,57 +1,55 @@
using Waf.NewsReader.Domain;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Waf.UnitTesting;
using Test.NewsReader.Domain.UnitTesting;
using Xunit;

namespace Test.NewsReader.Domain;

[TestClass]
public class FeedItemTest : DomainTest
public class FeedItemTest
{
[TestMethod]
[Fact]
public void ApplyValuesFromTest()
{
AssertHelper.ExpectedException<ArgumentNullException>(() => new FeedItem(null!, DateTimeOffset.Now, "test", "test"));

var itemA1 = new FeedItem(new("http://www.test.com/rss/feed"), new(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), "name", "desc");
Assert.AreEqual(new DateTimeOffset(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), itemA1.Date);
Assert.AreEqual("name", itemA1.Name);
Assert.AreEqual("desc", itemA1.Description);
Assert.IsFalse(itemA1.MarkAsRead);
Assert.Equal(new(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), itemA1.Date);
Assert.Equal("name", itemA1.Name);
Assert.Equal("desc", itemA1.Description);
Assert.False(itemA1.MarkAsRead);

var itemA2 = new FeedItem(new("http://www.test.com/rss/feed"), new(2022, 5, 5, 12, 0, 0, new(1, 0, 0)), "name2", "desc2");
itemA2.MarkAsRead = true;
itemA1.ApplyValuesFrom(itemA2);
Assert.AreEqual(new DateTimeOffset(2022, 5, 5, 12, 0, 0, new(1, 0, 0)), itemA1.Date);
Assert.AreEqual("name2", itemA1.Name);
Assert.AreEqual("desc2", itemA1.Description);
Assert.IsTrue(itemA1.MarkAsRead);
Assert.Equal(new(2022, 5, 5, 12, 0, 0, new(1, 0, 0)), itemA1.Date);
Assert.Equal("name2", itemA1.Name);
Assert.Equal("desc2", itemA1.Description);
Assert.True(itemA1.MarkAsRead);

var itemB1 = new FeedItem(new("http://www.test.com/rss/feed2"), new(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), "name", "desc");
AssertHelper.ExpectedException<InvalidOperationException>(() => itemA1.ApplyValuesFrom(itemB1));
}

[TestMethod]
[Fact]
public void CloneTest()
{
var item = new FeedItem(new("http://www.test.com/rss/feed"), new(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), "name", "desc");
item.MarkAsRead = true;
var clone = item.Clone();

Assert.AreNotSame(item, clone);
Assert.AreEqual(new DateTimeOffset(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), clone.Date);
Assert.AreEqual("name", clone.Name);
Assert.AreEqual("desc", clone.Description);
Assert.IsTrue(clone.MarkAsRead);
Assert.NotSame(item, clone);
Assert.Equal(new(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), clone.Date);
Assert.Equal("name", clone.Name);
Assert.Equal("desc", clone.Description);
Assert.True(clone.MarkAsRead);
}

[TestMethod]
[Fact]
public void SupportNull()
{
var item = new FeedItem(new("http://www.test.com/rss/feed"), new(2020, 5, 5, 12, 0, 0, new(1, 0, 0)), "name", "desc");
item.Name = null;
item.Description = null;
Assert.IsNull(item.Name);
Assert.IsNull(item.Description);
Assert.Null(item.Name);
Assert.Null(item.Description);
}
}
Loading

0 comments on commit 912bfa1

Please sign in to comment.