Skip to content

Commit e121f2c

Browse files
committed
test(default-entity-repository): add UpdateAsync tests
1 parent b1a4f1a commit e121f2c

File tree

3 files changed

+226
-6
lines changed

3 files changed

+226
-6
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using JsonApiDotNetCore.Controllers;
4+
using JsonApiDotNetCore.Internal;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Xunit;
7+
using Moq;
8+
using Microsoft.EntityFrameworkCore;
9+
using JsonApiDotNetCoreExample.Models;
10+
using JsonApiDotNetCore.Extensions;
11+
using JsonApiDotNetCore.Data;
12+
using JsonApiDotNetCore.Models;
13+
using Microsoft.Extensions.Logging;
14+
using JsonApiDotNetCore.Services;
15+
using System.Threading.Tasks;
16+
17+
namespace UnitTests.Data
18+
{
19+
public class DefaultEntityRepository_Tests : JsonApiControllerMixin
20+
{
21+
private readonly Mock<IJsonApiContext> _jsonApiContextMock;
22+
private readonly Mock<ILoggerFactory> _loggFactoryMock;
23+
private readonly Mock<DbSet<TodoItem>> _dbSetMock;
24+
private readonly Mock<DbContext> _contextMock;
25+
private readonly Mock<IDbContextResolver> _contextResolverMock;
26+
private readonly TodoItem _todoItem;
27+
private Dictionary<AttrAttribute, object> _attrsToUpdate = new Dictionary<AttrAttribute, object>();
28+
private Dictionary<RelationshipAttribute, object> _relationshipsToUpdate = new Dictionary<RelationshipAttribute, object>();
29+
30+
public DefaultEntityRepository_Tests()
31+
{
32+
_todoItem = new TodoItem
33+
{
34+
Id = 1,
35+
Description = Guid.NewGuid().ToString(),
36+
Ordinal = 10
37+
};
38+
_jsonApiContextMock = new Mock<IJsonApiContext>();
39+
_loggFactoryMock = new Mock<ILoggerFactory>();
40+
_dbSetMock = DbSetMock.Create<TodoItem>(new[] { _todoItem });
41+
_contextMock = new Mock<DbContext>();
42+
_contextResolverMock = new Mock<IDbContextResolver>();
43+
}
44+
45+
[Fact]
46+
public async Task UpdateAsync_Updates_Attributes_In_AttributesToUpdate()
47+
{
48+
// arrange
49+
var todoItemUpdates = new TodoItem
50+
{
51+
Id = _todoItem.Id,
52+
Description = Guid.NewGuid().ToString()
53+
};
54+
55+
_attrsToUpdate = new Dictionary<AttrAttribute, object>
56+
{
57+
{
58+
new AttrAttribute("description", "Description"),
59+
todoItemUpdates.Description
60+
}
61+
};
62+
63+
var repository = GetRepository();
64+
65+
// act
66+
var updatedItem = await repository.UpdateAsync(_todoItem.Id, todoItemUpdates);
67+
68+
// assert
69+
Assert.NotNull(updatedItem);
70+
Assert.Equal(_todoItem.Ordinal, updatedItem.Ordinal);
71+
Assert.Equal(todoItemUpdates.Description, updatedItem.Description);
72+
}
73+
74+
private DefaultEntityRepository<TodoItem> GetRepository()
75+
{
76+
_contextResolverMock
77+
.Setup(m => m.GetContext())
78+
.Returns(_contextMock.Object);
79+
80+
_contextResolverMock
81+
.Setup(m => m.GetDbSet<TodoItem>())
82+
.Returns(_dbSetMock.Object);
83+
84+
_jsonApiContextMock
85+
.Setup(m => m.AttributesToUpdate)
86+
.Returns(_attrsToUpdate);
87+
88+
_jsonApiContextMock
89+
.Setup(m => m.RelationshipsToUpdate)
90+
.Returns(_relationshipsToUpdate);
91+
92+
_jsonApiContextMock
93+
.Setup(m => m.GetDbContextResolver())
94+
.Returns(_contextResolverMock.Object);
95+
96+
return new DefaultEntityRepository<TodoItem>(
97+
_loggFactoryMock.Object,
98+
_jsonApiContextMock.Object);
99+
}
100+
}
101+
}

test/UnitTests/DbSetMock.cs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Linq.Expressions;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Microsoft.EntityFrameworkCore;
7+
using Microsoft.EntityFrameworkCore.Query.Internal;
8+
using Moq;
9+
10+
public static class DbSetMock
11+
{
12+
public static Mock<DbSet<T>> Create<T>(params T[] elements) where T : class
13+
{
14+
return new List<T>(elements).AsDbSetMock();
15+
}
16+
}
17+
18+
public static class ListExtensions
19+
{
20+
public static Mock<DbSet<T>> AsDbSetMock<T>(this List<T> list) where T : class
21+
{
22+
IQueryable<T> queryableList = list.AsQueryable();
23+
Mock<DbSet<T>> dbSetMock = new Mock<DbSet<T>>();
24+
25+
dbSetMock.As<IQueryable<T>>().Setup(x => x.Expression).Returns(queryableList.Expression);
26+
dbSetMock.As<IQueryable<T>>().Setup(x => x.ElementType).Returns(queryableList.ElementType);
27+
dbSetMock.As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(queryableList.GetEnumerator());
28+
29+
dbSetMock.As<IAsyncEnumerable<T>>().Setup(m => m.GetEnumerator()).Returns(new TestAsyncEnumerator<T>(queryableList.GetEnumerator()));
30+
dbSetMock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(new TestAsyncQueryProvider<T>(queryableList.Provider));
31+
return dbSetMock;
32+
}
33+
}
34+
35+
internal class TestAsyncQueryProvider<TEntity> : IAsyncQueryProvider
36+
{
37+
private readonly IQueryProvider _inner;
38+
39+
internal TestAsyncQueryProvider(IQueryProvider inner)
40+
{
41+
_inner = inner;
42+
}
43+
44+
public IQueryable CreateQuery(Expression expression)
45+
{
46+
return new TestAsyncEnumerable<TEntity>(expression);
47+
}
48+
49+
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
50+
{
51+
return new TestAsyncEnumerable<TElement>(expression);
52+
}
53+
54+
public object Execute(Expression expression)
55+
{
56+
return _inner.Execute(expression);
57+
}
58+
59+
public TResult Execute<TResult>(Expression expression)
60+
{
61+
return _inner.Execute<TResult>(expression);
62+
}
63+
64+
public IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression)
65+
{
66+
return new TestAsyncEnumerable<TResult>(expression);
67+
}
68+
69+
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
70+
{
71+
return Task.FromResult(Execute<TResult>(expression));
72+
}
73+
}
74+
75+
internal class TestAsyncEnumerable<T> : EnumerableQuery<T>, IAsyncEnumerable<T>, IQueryable<T>
76+
{
77+
public TestAsyncEnumerable(IEnumerable<T> enumerable)
78+
: base(enumerable)
79+
{ }
80+
81+
public TestAsyncEnumerable(Expression expression)
82+
: base(expression)
83+
{ }
84+
85+
public IAsyncEnumerator<T> GetEnumerator()
86+
{
87+
return new TestAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
88+
}
89+
90+
IQueryProvider IQueryable.Provider
91+
{
92+
get { return new TestAsyncQueryProvider<T>(this); }
93+
}
94+
}
95+
96+
internal class TestAsyncEnumerator<T> : IAsyncEnumerator<T>
97+
{
98+
private readonly IEnumerator<T> _inner;
99+
100+
public TestAsyncEnumerator(IEnumerator<T> inner)
101+
{
102+
_inner = inner;
103+
}
104+
105+
public void Dispose()
106+
{
107+
_inner.Dispose();
108+
}
109+
110+
public T Current
111+
{
112+
get
113+
{
114+
return _inner.Current;
115+
}
116+
}
117+
118+
public Task<bool> MoveNext(CancellationToken cancellationToken)
119+
{
120+
return Task.FromResult(_inner.MoveNext());
121+
}
122+
}

test/UnitTests/UnitTests.csproj

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
32
<PropertyGroup>
43
<TargetFramework>netcoreapp1.1</TargetFramework>
5-
64
<IsPackable>false</IsPackable>
75
</PropertyGroup>
8-
96
<ItemGroup>
107
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170427-09" />
8+
<PackageReference Include="moq" Version="4.7.10" />
119
<PackageReference Include="xunit" Version="2.2.0" />
1210
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
1311
</ItemGroup>
14-
1512
<ItemGroup>
1613
<ProjectReference Include="..\..\src\JsonApiDotNetCore\JsonApiDotNetCore.csproj" />
14+
<ProjectReference Include="..\..\src\JsonApiDotNetCoreExample\JsonApiDotNetCoreExample.csproj" />
1715
</ItemGroup>
18-
19-
</Project>
16+
</Project>

0 commit comments

Comments
 (0)