1
+ using System ;
2
+ using System . Linq . Expressions ;
3
+ using System . Threading . Tasks ;
4
+ using FluentAssertions ;
5
+ using LinkDotNet . Blog . Domain ;
6
+ using LinkDotNet . Blog . Infrastructure . Persistence ;
7
+ using LinkDotNet . Blog . TestUtilities ;
8
+ using Microsoft . Extensions . Caching . Memory ;
9
+ using Moq ;
10
+ using X . PagedList ;
11
+ using Xunit ;
12
+
13
+ namespace LinkDotNet . Blog . UnitTests . Infrastructure . Persistence
14
+ {
15
+ public class CachedRepositoryTests
16
+ {
17
+ private readonly Mock < IRepository < BlogPost > > repositoryMock ;
18
+ private readonly CachedRepository < BlogPost > sut ;
19
+
20
+ public CachedRepositoryTests ( )
21
+ {
22
+ repositoryMock = new Mock < IRepository < BlogPost > > ( ) ;
23
+ sut = new CachedRepository < BlogPost > ( repositoryMock . Object , new MemoryCache ( new MemoryCacheOptions ( ) ) ) ;
24
+ }
25
+
26
+ [ Fact ]
27
+ public async Task ShouldGetFromCacheWhenLoaded ( )
28
+ {
29
+ var blogPost = new BlogPostBuilder ( ) . Build ( ) ;
30
+ repositoryMock . Setup ( r => r . GetByIdAsync ( "id" ) ) . ReturnsAsync ( blogPost ) ;
31
+ var firstCall = await sut . GetByIdAsync ( "id" ) ;
32
+
33
+ var secondCall = await sut . GetByIdAsync ( "id" ) ;
34
+
35
+ firstCall . Should ( ) . Be ( secondCall ) ;
36
+ firstCall . Should ( ) . Be ( blogPost ) ;
37
+ repositoryMock . Verify ( r => r . GetByIdAsync ( "id" ) , Times . Once ) ;
38
+ }
39
+
40
+ [ Fact ]
41
+ public async Task ShouldGetAllFromCacheWhenLoaded ( )
42
+ {
43
+ var blogPost = new BlogPostBuilder ( ) . Build ( ) ;
44
+ repositoryMock . Setup ( r => r . GetAllAsync (
45
+ It . IsAny < Expression < Func < BlogPost , bool > > > ( ) ,
46
+ It . IsAny < Expression < Func < BlogPost , object > > > ( ) ,
47
+ It . IsAny < bool > ( ) ,
48
+ It . IsAny < int > ( ) ,
49
+ It . IsAny < int > ( ) ) )
50
+ . ReturnsAsync ( new PagedList < BlogPost > ( new [ ] { blogPost } , 1 , 1 ) ) ;
51
+ var firstCall = await sut . GetAllAsync ( ) ;
52
+
53
+ var secondCall = await sut . GetAllAsync ( ) ;
54
+
55
+ firstCall . Count . Should ( ) . Be ( 1 ) ;
56
+ secondCall . Count . Should ( ) . Be ( 1 ) ;
57
+ repositoryMock . Verify (
58
+ r => r . GetAllAsync (
59
+ It . IsAny < Expression < Func < BlogPost , bool > > > ( ) ,
60
+ It . IsAny < Expression < Func < BlogPost , object > > > ( ) ,
61
+ It . IsAny < bool > ( ) ,
62
+ It . IsAny < int > ( ) ,
63
+ It . IsAny < int > ( ) ) ,
64
+ Times . Once ) ;
65
+ }
66
+
67
+ [ Fact ]
68
+ public async Task ShouldNotCacheWhenParameterDifferent ( )
69
+ {
70
+ SetupRepository ( ) ;
71
+ await sut . GetAllAsync ( ) ;
72
+ await sut . GetAllAsync ( p => p . IsPublished ) ;
73
+ await sut . GetAllAsync ( p => p . IsPublished , p => p . Likes ) ;
74
+ await sut . GetAllAsync (
75
+ p => p . IsPublished ,
76
+ p => p . Likes ,
77
+ false ) ;
78
+ await sut . GetAllAsync (
79
+ p => p . IsPublished ,
80
+ p => p . Likes ,
81
+ false ,
82
+ 2 ) ;
83
+ await sut . GetAllAsync (
84
+ p => p . IsPublished ,
85
+ p => p . Likes ,
86
+ false ,
87
+ 2 ,
88
+ 30 ) ;
89
+
90
+ repositoryMock . Verify (
91
+ r => r . GetAllAsync (
92
+ It . IsAny < Expression < Func < BlogPost , bool > > > ( ) ,
93
+ It . IsAny < Expression < Func < BlogPost , object > > > ( ) ,
94
+ It . IsAny < bool > ( ) ,
95
+ It . IsAny < int > ( ) ,
96
+ It . IsAny < int > ( ) ) ,
97
+ Times . Exactly ( 6 ) ) ;
98
+ }
99
+
100
+ [ Fact ]
101
+ public async Task ShouldUpdateCacheOnStore ( )
102
+ {
103
+ var blogPost = new BlogPostBuilder ( ) . Build ( ) ;
104
+ blogPost . Id = "id" ;
105
+ repositoryMock . Setup ( r => r . GetByIdAsync ( "id" ) ) . ReturnsAsync ( blogPost ) ;
106
+ await sut . GetByIdAsync ( "id" ) ;
107
+ var update = new BlogPostBuilder ( ) . WithTitle ( "new" ) . Build ( ) ;
108
+ blogPost . Update ( update ) ;
109
+ await sut . StoreAsync ( blogPost ) ;
110
+
111
+ var latest = await sut . GetByIdAsync ( "id" ) ;
112
+
113
+ latest . Title . Should ( ) . Be ( "new" ) ;
114
+ }
115
+
116
+ [ Fact ]
117
+ public async Task ShouldDelete ( )
118
+ {
119
+ await sut . DeleteAsync ( "id" ) ;
120
+
121
+ repositoryMock . Verify ( r => r . DeleteAsync ( "id" ) , Times . Once ) ;
122
+ }
123
+
124
+ private void SetupRepository ( )
125
+ {
126
+ var blogPost = new BlogPostBuilder ( ) . Build ( ) ;
127
+ repositoryMock . Setup ( r => r . GetAllAsync (
128
+ It . IsAny < Expression < Func < BlogPost , bool > > > ( ) ,
129
+ It . IsAny < Expression < Func < BlogPost , object > > > ( ) ,
130
+ It . IsAny < bool > ( ) ,
131
+ It . IsAny < int > ( ) ,
132
+ It . IsAny < int > ( ) ) )
133
+ . ReturnsAsync ( new PagedList < BlogPost > ( new [ ] { blogPost } , 1 , 1 ) ) ;
134
+ }
135
+ }
136
+ }
0 commit comments