Skip to content

Commit 20377bc

Browse files
committed
feat: 新增领域事件单元测试
1 parent 2d5145e commit 20377bc

File tree

9 files changed

+278
-6
lines changed

9 files changed

+278
-6
lines changed

Bing.All.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bing.TextTemplating", "fram
224224
EndProject
225225
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bing.TextTemplating.Scriban", "framework\src\Bing.TextTemplating.Scriban\Bing.TextTemplating.Scriban.csproj", "{65B439C9-4B54-4DB8-86B3-9EBE8E62DF83}"
226226
EndProject
227+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bing.Test.Shared", "framework\tests\Bing.Test.Shared\Bing.Test.Shared.csproj", "{D6C96AE5-8756-4278-A331-43073E08C3ED}"
228+
EndProject
229+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bing.Ddd.Domain.Tests", "framework\tests\Bing.Ddd.Domain.Tests\Bing.Ddd.Domain.Tests.csproj", "{8B581529-D7D2-4DCF-824A-2AAFB58F8C94}"
230+
EndProject
227231
Global
228232
GlobalSection(SolutionConfigurationPlatforms) = preSolution
229233
Debug|Any CPU = Debug|Any CPU
@@ -498,6 +502,14 @@ Global
498502
{65B439C9-4B54-4DB8-86B3-9EBE8E62DF83}.Debug|Any CPU.Build.0 = Debug|Any CPU
499503
{65B439C9-4B54-4DB8-86B3-9EBE8E62DF83}.Release|Any CPU.ActiveCfg = Release|Any CPU
500504
{65B439C9-4B54-4DB8-86B3-9EBE8E62DF83}.Release|Any CPU.Build.0 = Release|Any CPU
505+
{D6C96AE5-8756-4278-A331-43073E08C3ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
506+
{D6C96AE5-8756-4278-A331-43073E08C3ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
507+
{D6C96AE5-8756-4278-A331-43073E08C3ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
508+
{D6C96AE5-8756-4278-A331-43073E08C3ED}.Release|Any CPU.Build.0 = Release|Any CPU
509+
{8B581529-D7D2-4DCF-824A-2AAFB58F8C94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
510+
{8B581529-D7D2-4DCF-824A-2AAFB58F8C94}.Debug|Any CPU.Build.0 = Debug|Any CPU
511+
{8B581529-D7D2-4DCF-824A-2AAFB58F8C94}.Release|Any CPU.ActiveCfg = Release|Any CPU
512+
{8B581529-D7D2-4DCF-824A-2AAFB58F8C94}.Release|Any CPU.Build.0 = Release|Any CPU
501513
EndGlobalSection
502514
GlobalSection(SolutionProperties) = preSolution
503515
HideSolutionNode = FALSE
@@ -596,6 +608,8 @@ Global
596608
{09A94120-CE45-402F-B45A-21DF04F0C226} = {3030FE3D-DB8F-403D-A181-8152670827AB}
597609
{E06DC786-72AB-417B-ACDB-AF00688544EA} = {09A94120-CE45-402F-B45A-21DF04F0C226}
598610
{65B439C9-4B54-4DB8-86B3-9EBE8E62DF83} = {09A94120-CE45-402F-B45A-21DF04F0C226}
611+
{D6C96AE5-8756-4278-A331-43073E08C3ED} = {5C7976B4-C243-41B9-8303-8E8FAE099D31}
612+
{8B581529-D7D2-4DCF-824A-2AAFB58F8C94} = {5C7976B4-C243-41B9-8303-8E8FAE099D31}
599613
EndGlobalSection
600614
GlobalSection(ExtensibilityGlobals) = postSolution
601615
SolutionGuid = {C1202A0F-83CC-4602-BCE5-20CB640BCAD4}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Threading.Tasks;
2+
3+
namespace Bing.Aspects
4+
{
5+
/// <summary>
6+
/// 拦截器
7+
/// </summary>
8+
public interface IBingInterceptor
9+
{
10+
/// <summary>
11+
/// 拦截
12+
/// </summary>
13+
/// <param name="invocation">方法调用</param>
14+
Task InterceptAsync(IBingMethodInvocation invocation);
15+
}
16+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System.Collections.Generic;
2+
using System.Reflection;
3+
using System.Threading.Tasks;
4+
5+
namespace Bing.Aspects
6+
{
7+
/// <summary>
8+
/// 方法调用
9+
/// </summary>
10+
public interface IBingMethodInvocation
11+
{
12+
/// <summary>
13+
/// 目标对象
14+
/// </summary>
15+
object TargetObject { get; }
16+
17+
/// <summary>
18+
/// 方法
19+
/// </summary>
20+
MethodInfo Method { get; }
21+
22+
/// <summary>
23+
/// 参数数组
24+
/// </summary>
25+
object[] Parameters { get; }
26+
27+
/// <summary>
28+
/// 返回值
29+
/// </summary>
30+
object ReturnValue { get; set; }
31+
32+
/// <summary>
33+
/// 属性
34+
/// </summary>
35+
IDictionary<string, object> Properties { get; }
36+
37+
/// <summary>
38+
/// 处理并继续
39+
/// </summary>
40+
Task ProceedAsync();
41+
}
42+
}

framework/src/Bing/Bing/DisposeAction.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using Bing.Helpers;
32

43
namespace Bing
54
{
@@ -17,11 +16,7 @@ public class DisposeAction : IDisposable
1716
/// 初始化一个<see cref="DisposeAction"/>类型的实例
1817
/// </summary>
1918
/// <param name="action">操作</param>
20-
public DisposeAction(Action action)
21-
{
22-
Check.NotNull(action, nameof(action));
23-
_action = action;
24-
}
19+
public DisposeAction(Action action) => _action = action ?? throw new ArgumentNullException(nameof(action));
2520

2621
/// <summary>
2722
/// 释放资源
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<RootNamespace />
6+
<IsPackable>false</IsPackable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
11+
<PackageReference Include="xunit" Version="2.4.1" />
12+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
13+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
14+
<PrivateAssets>all</PrivateAssets>
15+
</PackageReference>
16+
<PackageReference Include="coverlet.collector" Version="1.3.0">
17+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18+
<PrivateAssets>all</PrivateAssets>
19+
</PackageReference>
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<ProjectReference Include="..\..\src\Bing.Ddd.Domain\Bing.Ddd.Domain.csproj" />
24+
<ProjectReference Include="..\Bing.Test.Shared\Bing.Test.Shared.csproj" />
25+
</ItemGroup>
26+
27+
</Project>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System.Threading.Tasks;
2+
using Bing.Test.Shared;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Xunit;
5+
6+
namespace Bing.Domain.Entities.Events
7+
{
8+
public class DomainEventHandlerTest : IntegrationTestBase
9+
{
10+
internal class EmployeeCreatedEventHandler1 : IDomainEventHandler<EntityCreatedEvent<Employee>>
11+
{
12+
public static string FirstName { get; private set; }
13+
14+
/// <summary>
15+
/// 处理
16+
/// </summary>
17+
/// <param name="event">领域事件</param>
18+
public Task HandleAsync(EntityCreatedEvent<Employee> @event)
19+
{
20+
var employee = @event.Entity;
21+
FirstName = employee.FirstName;
22+
return Task.CompletedTask;
23+
}
24+
}
25+
26+
internal class EmployeeCreatedEventHandler2 : IDomainEventHandler<EntityCreatedEvent<Employee>>
27+
{
28+
public static string LastName { get; private set; }
29+
30+
/// <summary>
31+
/// 处理
32+
/// </summary>
33+
/// <param name="event">领域事件</param>
34+
public Task HandleAsync(EntityCreatedEvent<Employee> @event)
35+
{
36+
var employee = @event.Entity;
37+
LastName = employee.LastName;
38+
return Task.CompletedTask;
39+
}
40+
}
41+
42+
private readonly IDomainEventDispatcher _dispatcher;
43+
44+
public DomainEventHandlerTest()
45+
{
46+
_dispatcher = ServiceProvider.GetRequiredService<IDomainEventDispatcher>();
47+
}
48+
49+
/// <summary>
50+
/// 配置服务
51+
/// </summary>
52+
/// <param name="services">服务集合</param>
53+
protected override void ConfigureServices(IServiceCollection services)
54+
{
55+
services.AddDomainEventDispatcher();
56+
}
57+
58+
[Fact]
59+
public async Task Handle_SubscribeMultipleEventHandlers_TriggerAllHandlers()
60+
{
61+
var employee = new Employee("Allen", "Yeager", "1");
62+
var @event = new EntityCreatedEvent<Employee>(employee);
63+
await _dispatcher.DispatchAsync(@event);
64+
Assert.Equal(employee.FirstName, EmployeeCreatedEventHandler1.FirstName);
65+
Assert.Equal(employee.LastName, EmployeeCreatedEventHandler2.LastName);
66+
}
67+
}
68+
69+
public class EntityCreatedEvent<TEntity> : DomainEvent
70+
{
71+
public TEntity Entity { get; }
72+
73+
public EntityCreatedEvent(TEntity entity)
74+
{
75+
Entity = entity;
76+
}
77+
}
78+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace Bing.Domain.Entities.Events
2+
{
3+
internal class Employee : AggregateRoot<Employee, int>
4+
{
5+
public string FirstName { get; private set; }
6+
7+
public string LastName { get; private set; }
8+
9+
public string Number { get; private set; }
10+
11+
public Employee(
12+
string firstName,
13+
string lastName,
14+
string number)
15+
{
16+
FirstName = firstName;
17+
LastName = lastName;
18+
Number = number;
19+
}
20+
}
21+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.19" />
9+
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.19" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Logging;
4+
using Microsoft.Extensions.Logging.Abstractions;
5+
6+
namespace Bing.Test.Shared
7+
{
8+
/// <summary>
9+
/// 集成测试基类
10+
/// </summary>
11+
public abstract class IntegrationTestBase : IDisposable
12+
{
13+
/// <summary>
14+
/// 服务提供程序
15+
/// </summary>
16+
protected IServiceProvider ServiceProvider { get; private set; }
17+
18+
/// <summary>
19+
/// 服务作用域
20+
/// </summary>
21+
protected IServiceScope ServiceScope { get; private set; }
22+
23+
/// <summary>
24+
/// 初始化一个<see cref="IntegrationTestBase"/>类型的实例
25+
/// </summary>
26+
protected IntegrationTestBase() => Initialize();
27+
28+
/// <summary>
29+
/// 初始化
30+
/// </summary>
31+
protected void Initialize()
32+
{
33+
var serviceCollection = new ServiceCollection();
34+
serviceCollection.AddLogging(x => x.AddProvider(NullLoggerProvider.Instance));
35+
ConfigureServices(serviceCollection);
36+
if (ServiceProvider != null)
37+
return;
38+
ServiceProvider = serviceCollection.BuildServiceProvider();
39+
ServiceScope = ServiceProvider.CreateScope();
40+
}
41+
42+
/// <summary>
43+
/// 配置服务
44+
/// </summary>
45+
/// <param name="services">服务集合</param>
46+
protected abstract void ConfigureServices(IServiceCollection services);
47+
48+
/// <summary>
49+
/// 释放资源
50+
/// </summary>
51+
/// <param name="disposing">是否释放资源中</param>
52+
protected virtual void Dispose(bool disposing)
53+
{
54+
if (disposing)
55+
ServiceScope?.Dispose();
56+
}
57+
58+
/// <summary>
59+
/// 释放资源
60+
/// </summary>
61+
public void Dispose()
62+
{
63+
Dispose(true);
64+
GC.SuppressFinalize(this);
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)