Skip to content
This repository was archived by the owner on Apr 20, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Build Configurations/Templates/Test Net Core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
parameters:
- name: projects
type: string
default: '**/*[Tt]ests/*.csproj'

- name: buildConfiguration
type: string
default: 'Release'

steps:
- task: DotNetCoreCLI@2
displayName: 'Run unit tests'
inputs:
command: 'test'
projects: '${{parameters.projects}}'
arguments: '--configuration ${{parameters.buildConfiguration}}'
4 changes: 3 additions & 1 deletion Build Configurations/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ steps:
projects: '**/NetCoreEntityFramework.csproj'
buildConfiguration: '$(buildConfiguration)'
skipBuild: true
skipInstall: true
skipInstall: true

- template: 'Templates/Test Net Core.yml'
274 changes: 274 additions & 0 deletions NetCoreEntityFramework.Tests/EntityRepositoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
using AutoFixture.NUnit3;
using Microsoft.EntityFrameworkCore;
using Nodes.NetCore.EntityFramework.Tests.Mocks;
using NUnit.Framework;
using System;
using System.Threading.Tasks;
using TestContext = Nodes.NetCore.EntityFramework.Tests.Mocks.TestContext;

namespace Nodes.NetCore.EntityFramework.Tests
{
public class EntityRepositoryTests
{
private TestEntityRepository _repository;
private TestContext _context;
private TestEntity _entity;
private TestEntity _deletedEntity;

[SetUp]
public void Setup()
{
var options = new DbContextOptionsBuilder<TestContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;

_context = new TestContext(options);

_repository = new TestEntityRepository(_context);

DateTime now = DateTime.UtcNow;

_entity = new TestEntity
{
Created = now,
Deleted = false,
Id = Guid.NewGuid(),
Updated = now,
Property = string.Empty
};

_deletedEntity = new TestEntity
{
Created = now.AddMinutes(-42),
Deleted = true,
DeletedAt = now,
Id = Guid.NewGuid(),
Updated = now.AddMinutes(-42),
Property = "I'm deleted"
};

_context.Table.Add(_entity);
_context.Table.Add(_deletedEntity);

_context.SaveChanges();

_repository = new TestEntityRepository(_context);
}

#region Add
[Test]
public async Task AddAddsEntityAndSetsAttributes()
{
int startSize = await _context.Table.CountAsync();
int expectedSize = startSize + 1;
var entity = new TestEntity();

using(_repository)
{
await _repository.Add(entity);
}

Assert.NotNull(entity.Id);
Assert.AreNotEqual(default(DateTime), entity.Created);
Assert.AreNotEqual(default(DateTime), entity.Updated);
Assert.IsFalse(entity.Deleted);
Assert.AreEqual(expectedSize, await _context.Table.CountAsync());
}

[Test]
public async Task AddEntityWithIdKeepsId()
{
Guid id = Guid.NewGuid();
var entity = new TestEntity
{
Id = id
};

using (_repository)
{
await _repository.Add(entity);
}

Assert.AreEqual(id, entity.Id);
}

[Test]
public void AddThrowsExceptionIfEntityIsNull()
{
Assert.ThrowsAsync<ArgumentNullException>(() => _repository.Add(null));
}
#endregion

#region Get
[Test]
public async Task GetValidEntityReturnsEntity()
{
var entity = await _repository.Get((Guid)_entity.Id);

Assert.AreSame(_entity, entity);
}

[Test]
public async Task DontGetDeletedEntityWithoutFlag()
{
var entity = await _repository.Get((Guid)_deletedEntity.Id);

Assert.IsNull(entity);
}

[Test]
public async Task GetDeletedEntityWithFlag()
{
var entity = await _repository.Get((Guid)_deletedEntity.Id, true);

Assert.AreSame(_deletedEntity, entity);
}
#endregion

#region Update
[Test]
[AutoData]
public async Task UpdateUpdatesUpdated(string propertyValue)
{
DateTime oldUpdated = _entity.Updated;
DateTime oldCreated = _entity.Created;
_entity.Property = propertyValue;

using(_repository)
{
await _repository.Update(_entity);
}

var entity = await _repository.Get((Guid)_entity.Id);

Assert.AreEqual(propertyValue, entity.Property);
Assert.AreNotEqual(oldUpdated, entity.Updated);
Assert.AreEqual(oldCreated, entity.Created);
}

[Test]
public void UpdateThrowsExceptionIfNull()
{
Assert.ThrowsAsync<ArgumentNullException>(() => _repository.Update(null));
}
#endregion

#region Delete
[Test]
public async Task DeleteSoftDeletesAndSetsDeletedAt()
{
bool success;
using(_repository)
{
success = await _repository.Delete(_entity);
}

var newlyDeletedEntity = await _repository.Get((Guid)_entity.Id, true);
Assert.IsTrue(success);
Assert.IsTrue(newlyDeletedEntity.Deleted);
Assert.NotNull(newlyDeletedEntity.DeletedAt);
}

[Test]
public void DeleteThrowsExceptionIfArgumentNull()
{
Assert.ThrowsAsync<ArgumentNullException>(() => _repository.Delete(null));
}

[Test]
public async Task DeleteWithValidIdDeletesAndSetsDeletedAt()
{
bool success;
Guid id = (Guid)_entity.Id;
using (_repository)
{
success = await _repository.Delete(id);
}

var newlyDeletedEntity = await _repository.Get(id, true);
Assert.IsTrue(success);
Assert.IsTrue(newlyDeletedEntity.Deleted);
Assert.NotNull(newlyDeletedEntity.DeletedAt);
}

[Test]
[AutoData]
public async Task DeleteWithInvalidIdReturnsFalse(Guid randomId)
{
bool success;

using(_repository)
{
success = await _repository.Delete(randomId);
}

Assert.IsFalse(success);
}

[Test]
public void DeleteWithEmptyGuidThrowsException()
{
Assert.ThrowsAsync<ArgumentException>(() => _repository.Delete(Guid.Empty));
}
#endregion

#region Restore
[Test]
public async Task RestoreSetsDeletedFalse()
{
bool success;

using(_repository)
{
success = await _repository.Restore(_deletedEntity);
}

var restoredEntity = await _repository.Get((Guid)_deletedEntity.Id);
Assert.IsTrue(success);
Assert.IsFalse(restoredEntity?.Deleted);
}

[Test]
public void RestoreThrowsExceptionWhenEntityNull()
{
Assert.ThrowsAsync<ArgumentNullException>(() => _repository.Restore(null));
}

[Test]
public async Task RestoreOnIdSetsDeletedFalse()
{
bool success;
Guid id = (Guid)_deletedEntity.Id;

using (_repository)
{
success = await _repository.Restore(id);
}

var restoredEntity = await _repository.Get(id);
Assert.IsTrue(success);
Assert.IsFalse(restoredEntity?.Deleted);
}

[Test]
[AutoData]
public async Task RestoreOnInvalidIdReturnsFalse(Guid randomId)
{
bool success;

using(_repository)
{
success = await _repository.Restore(randomId);
}

Assert.IsFalse(success);
}

[Test]
public void RestoreOnEmptyGuidThrowsException()
{
Assert.ThrowsAsync<ArgumentException>(() => _repository.Restore(Guid.Empty));
}
#endregion
}
}
11 changes: 11 additions & 0 deletions NetCoreEntityFramework.Tests/Mocks/TestContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Microsoft.EntityFrameworkCore;

namespace Nodes.NetCore.EntityFramework.Tests.Mocks
{
public class TestContext : DbContext
{
public TestContext(DbContextOptions options) : base(options) { }

public DbSet<TestEntity> Table { get; set; }
}
}
9 changes: 9 additions & 0 deletions NetCoreEntityFramework.Tests/Mocks/TestEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Nodes.NetCore.EntityFramework.Models;

namespace Nodes.NetCore.EntityFramework.Tests.Mocks
{
public class TestEntity : EntityBase
{
public string Property { get; set; }
}
}
11 changes: 11 additions & 0 deletions NetCoreEntityFramework.Tests/Mocks/TestEntityRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Nodes.NetCore.EntityFramework.Repositories;

namespace Nodes.NetCore.EntityFramework.Tests.Mocks
{
public class TestEntityRepository : EntityRepository<TestEntity, TestContext>
{
public TestEntityRepository(TestContext context) : base(context, context.Table)
{
}
}
}
28 changes: 28 additions & 0 deletions NetCoreEntityFramework.Tests/NetCoreEntityFramework.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>

<AssemblyName>Nodes.NetCore.EntityFramework.Tests</AssemblyName>

<RootNamespace>Nodes.NetCore.EntityFramework.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoFixture.NUnit3" Version="4.11.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.3" />
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NetCoreEntityFramework\NetCoreEntityFramework.csproj" />
</ItemGroup>

</Project>
8 changes: 7 additions & 1 deletion NetCoreEntityFramework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29905.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCoreEntityFramework", "NetCoreEntityFramework\NetCoreEntityFramework.csproj", "{30F23EBE-4571-4215-8D70-F776A71BA51E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCoreEntityFramework", "NetCoreEntityFramework\NetCoreEntityFramework.csproj", "{30F23EBE-4571-4215-8D70-F776A71BA51E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCoreEntityFramework.Tests", "NetCoreEntityFramework.Tests\NetCoreEntityFramework.Tests.csproj", "{170EDF01-1CAD-49CF-9837-D0076667247B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -15,6 +17,10 @@ Global
{30F23EBE-4571-4215-8D70-F776A71BA51E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30F23EBE-4571-4215-8D70-F776A71BA51E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30F23EBE-4571-4215-8D70-F776A71BA51E}.Release|Any CPU.Build.0 = Release|Any CPU
{170EDF01-1CAD-49CF-9837-D0076667247B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{170EDF01-1CAD-49CF-9837-D0076667247B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{170EDF01-1CAD-49CF-9837-D0076667247B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{170EDF01-1CAD-49CF-9837-D0076667247B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
3 changes: 1 addition & 2 deletions NetCoreEntityFramework/Models/EntityBase.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore;
using System;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

Expand Down
Loading