mirror of https://github.com/abpframework/abp.git
12 changed files with 277 additions and 2 deletions
@ -0,0 +1,7 @@ |
|||
using Volo.Abp.TestApp.Testing; |
|||
|
|||
namespace Volo.Abp.EntityFrameworkCore.Domain; |
|||
|
|||
public class EntityCache_Tests : EntityCache_Tests<AbpEntityFrameworkCoreTestModule> |
|||
{ |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.TestApp.Testing; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.MongoDB.Domain; |
|||
|
|||
[Collection(MongoTestCollection.Name)] |
|||
public class EntityCache_Tests : EntityCache_Tests<AbpMongoDbTestModule> |
|||
{ |
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Caching.Distributed; |
|||
using Microsoft.Extensions.Caching.Memory; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.TestApp; |
|||
|
|||
[DisableConventionalRegistration] |
|||
public class TestMemoryDistributedCache : MemoryDistributedCache, ICacheSupportsMultipleItems |
|||
{ |
|||
public TestMemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor) |
|||
: base(optionsAccessor) |
|||
{ |
|||
} |
|||
|
|||
public TestMemoryDistributedCache(IOptions<MemoryDistributedCacheOptions> optionsAccessor, ILoggerFactory loggerFactory) |
|||
: base(optionsAccessor, loggerFactory) |
|||
{ |
|||
} |
|||
|
|||
public byte[][] GetMany(IEnumerable<string> keys) |
|||
{ |
|||
var values = new List<byte[]>(); |
|||
foreach (var key in keys) |
|||
{ |
|||
values.Add(Get(key)); |
|||
} |
|||
return values.ToArray(); |
|||
} |
|||
|
|||
public async Task<byte[][]> GetManyAsync(IEnumerable<string> keys, CancellationToken token = default) |
|||
{ |
|||
var values = new List<byte[]>(); |
|||
foreach (var key in keys) |
|||
{ |
|||
values.Add(await GetAsync(key, token)); |
|||
} |
|||
return values.ToArray(); |
|||
} |
|||
|
|||
public void SetMany(IEnumerable<KeyValuePair<string, byte[]>> items, DistributedCacheEntryOptions options) |
|||
{ |
|||
foreach (var item in items) |
|||
{ |
|||
Set(item.Key, item.Value, options); |
|||
} |
|||
} |
|||
|
|||
public async Task SetManyAsync(IEnumerable<KeyValuePair<string, byte[]>> items, DistributedCacheEntryOptions options, CancellationToken token = default) |
|||
{ |
|||
foreach (var item in items) |
|||
{ |
|||
await SetAsync(item.Key, item.Value, options, token); |
|||
} |
|||
} |
|||
|
|||
public void RefreshMany(IEnumerable<string> keys) |
|||
{ |
|||
foreach (var key in keys) |
|||
{ |
|||
Refresh(key); |
|||
} |
|||
} |
|||
|
|||
public async Task RefreshManyAsync(IEnumerable<string> keys, CancellationToken token = default) |
|||
{ |
|||
foreach (var key in keys) |
|||
{ |
|||
await RefreshAsync(key, token); |
|||
} |
|||
} |
|||
|
|||
public void RemoveMany(IEnumerable<string> keys) |
|||
{ |
|||
foreach (var key in keys) |
|||
{ |
|||
Remove(key); |
|||
} |
|||
} |
|||
|
|||
public async Task RemoveManyAsync(IEnumerable<string> keys, CancellationToken token = default) |
|||
{ |
|||
foreach (var key in keys) |
|||
{ |
|||
await RemoveAsync(key, token); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,133 @@ |
|||
using System; |
|||
using System.Text.Json.Serialization; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Entities.Caching; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Modularity; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.TestApp.Testing; |
|||
|
|||
public class EntityCache_Tests<TStartupModule> : TestAppTestBase<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
protected readonly IRepository<Product, Guid> ProductRepository; |
|||
protected readonly IEntityCache<Product, Guid> ProductEntityCache; |
|||
protected readonly IEntityCache<ProductCacheItem, Guid> ProductCacheItem; |
|||
|
|||
public EntityCache_Tests() |
|||
{ |
|||
ProductRepository = GetRequiredService<IRepository<Product, Guid>>(); |
|||
ProductEntityCache = GetRequiredService<IEntityCache<Product, Guid>>(); |
|||
ProductCacheItem = GetRequiredService<IEntityCache<ProductCacheItem, Guid>>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Return_Null_IF_Entity_Not_Exist() |
|||
{ |
|||
var notExistId = Guid.NewGuid(); |
|||
(await ProductEntityCache.FindAsync(notExistId)).ShouldBeNull(); |
|||
(await ProductCacheItem.FindAsync(notExistId)).ShouldBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Throw_EntityNotFoundException_IF_Entity_Not_Exist() |
|||
{ |
|||
var notExistId = Guid.NewGuid(); |
|||
await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductEntityCache.GetAsync(notExistId)); |
|||
await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductCacheItem.GetAsync(notExistId)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Return_EntityCache() |
|||
{ |
|||
var id = Guid.NewGuid(); |
|||
var product = await ProductRepository.InsertAsync(new Product(id, "Product1", decimal.One)); |
|||
|
|||
product = await ProductEntityCache.FindAsync(product.Id); |
|||
product.ShouldNotBeNull(); |
|||
product.Id.ShouldBe(id); |
|||
product.Name.ShouldBe("Product1"); |
|||
product.Price.ShouldBe(decimal.One); |
|||
|
|||
var productCacheItem = await ProductCacheItem.FindAsync(product.Id); |
|||
productCacheItem.ShouldNotBeNull(); |
|||
productCacheItem.Id.ShouldBe(id); |
|||
productCacheItem.Name.ShouldBe("Product1"); |
|||
productCacheItem.Price.ShouldBe(decimal.One); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Return_Null_IF_Deleted() |
|||
{ |
|||
var id = Guid.NewGuid(); |
|||
var product = await ProductRepository.InsertAsync(new Product(id, "Product1", decimal.One)); |
|||
(await ProductEntityCache.FindAsync(id)).ShouldNotBeNull(); |
|||
(await ProductCacheItem.FindAsync(id)).ShouldNotBeNull(); |
|||
|
|||
await ProductRepository.DeleteAsync(id); |
|||
|
|||
(await ProductEntityCache.FindAsync(product.Id)).ShouldBeNull(); |
|||
(await ProductCacheItem.FindAsync(product.Id)).ShouldBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Return_New_EntityCache_IF_Updated() |
|||
{ |
|||
var id = Guid.NewGuid(); |
|||
var product = await ProductRepository.InsertAsync(new Product(id, "Product1", decimal.One)); |
|||
(await ProductEntityCache.FindAsync(id)).ShouldNotBeNull(); |
|||
(await ProductCacheItem.FindAsync(id)).ShouldNotBeNull(); |
|||
|
|||
product.Name = "Product2"; |
|||
product.Price = decimal.Zero; |
|||
await ProductRepository.UpdateAsync(product); |
|||
|
|||
product = await ProductEntityCache.FindAsync(product.Id); |
|||
product.ShouldNotBeNull(); |
|||
product.Id.ShouldBe(id); |
|||
product.Name.ShouldBe("Product2"); |
|||
product.Price.ShouldBe(decimal.Zero); |
|||
|
|||
var productCacheItem = await ProductCacheItem.FindAsync(product.Id); |
|||
productCacheItem.ShouldNotBeNull(); |
|||
productCacheItem.Id.ShouldBe(id); |
|||
productCacheItem.Name.ShouldBe("Product2"); |
|||
productCacheItem.Price.ShouldBe(decimal.Zero); |
|||
} |
|||
} |
|||
|
|||
[Serializable] |
|||
public class Product : Entity<Guid> |
|||
{ |
|||
public Product() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public Product(Guid id, string name, decimal price) |
|||
{ |
|||
Id = id; |
|||
Name = name; |
|||
Price = price; |
|||
} |
|||
|
|||
[JsonInclude] |
|||
public override Guid Id { get; protected set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public decimal Price { get; set; } |
|||
} |
|||
|
|||
[Serializable] |
|||
public class ProductCacheItem |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public decimal Price { get; set; } |
|||
} |
|||
Loading…
Reference in new issue