AuthTests
类中的测试检查安全终结点是否:
- 将未经身份验证的用户重定向到应用的登录页面。
- 为经过身份验证的用户返回内容。
在 SUT 中,/SecurePage
页面使用 AuthorizePage 约定,将 AuthorizeFilter 应用到页面。 有关详细信息,请参阅 Razor Pages 授权约定。
C#复制
在 Get_SecurePageRedirectsAnUnauthenticatedUser
测试中,通过将 AllowAutoRedirect 设置为 false
,将 WebApplicationFactoryClientOptions 设置为不允许重定向:
C#复制
通过禁止客户端追随重定向,可以执行以下检查:
- 可以根据预期HttpStatusCode.Redirect 结果检查 SUT 返回的状态代码,而不是在重定向到登录页面之后的最终状态代码(这会是HttpStatusCode.OK)。
- 检查响应标头中的
Location
标头值,以确认它以http://localhost/Identity/Account/Login
开头,而不是最终登录页面响应(其中Location
标头不存在)。
测试应用可以在 ConfigureTestServices 中模拟 AuthenticationHandler<TOptions>,以便测试身份验证和授权的各个方面。 最小方案返回 AuthenticateResult.Success:
C#复制
当身份验证方案设置为 Test
(其中为 ConfigureTestServices
注册了 AddAuthentication
)时,会调用 TestAuthHandler
以对用户进行身份验证。 Test
架构必须与应用所需的架构匹配,这一点很重要。 否则,身份验证将不起作用。
C#复制
有关 WebApplicationFactoryClientOptions
的详细信息,请参阅客户端选项部分。
设置环境
默认情况下,SUT 的主机和应用环境配置为使用开发环境。 使用 IHostBuilder
时替代 SUT 的环境:
- 设置
ASPNETCORE_ENVIRONMENT
环境变量(例如,Staging
、Production
或其他自定义值,例如Testing
)。 - 在测试应用中替代
CreateHostBuilder
,以读取以ASPNETCORE
为前缀的环境变量。
C#复制
如果 SUT 使用 Web 主机 (IWebHostBuilder
),则替代 CreateWebHostBuilder
:
C#复制
测试基础结构如何推断应用内容根路径
WebApplicationFactory
构造函数通过在包含集成测试的程序集中搜索键等于 TEntryPoint
程序集 System.Reflection.Assembly.FullName
的 WebApplicationFactoryContentRootAttribute,来推断应用内容根路径。 如果找不到具有正确键的属性,则 WebApplicationFactory
会回退到搜索解决方案文件 (.sln) 并将 TEntryPoint
程序集名称追加到解决方案目录。 应用根目录(内容根路径)用于发现视图和内容文件。
禁用卷影复制
卷影复制会导致在与输出目录不同的目录中执行测试。 如果测试需要加载相对于 Assembly.Location
的文件,而你遇到问题,那么你可能需要禁用卷影复制。
若要在使用 xUnit 时禁用卷影复制,请通过正确的配置设置在测试项目目录中创建 xunit.runner.json
文件:
JSON复制
对象的处置
执行 IClassFixture
实现的测试之后,当 xUnit 处置 时,TestServer 和 WebApplicationFactoryHttpClient 会进行处置。 如果开发者实例化的对象需要处置,请在 IClassFixture
实现中处置它们。 有关详细信息,请参阅实现 Dispose 方法。
集成测试示例
示例应用包含两个应用:
应用 | 项目目录 | 描述 |
消息应用 (SUT) | | 允许用户添加消息、删除一个消息、删除所有消息和分析消息。 |
测试应用 | | 用于集成测试 SUT。 |
可使用 IDE 的内置测试功能(例如 Visual Studio)运行测试。 如果使用 Visual Studio Code 或命令行,请在 tests/RazorPagesProject.Tests
目录中的命令提示符处执行以下命令:
控制台复制
消息应用 (SUT) 组织
SUT 是具有以下特征的 Razor Pages 消息系统:
- 应用的索引页面(
Pages/Index.cshtml
和Pages/Index.cshtml.cs
)提供 UI 和页面模型方法,用于控制添加、删除和分析消息(每个消息的平均字词数)。 - 消息由
Message
类 (Data/Message.cs
) 描述,并具有两个属性:Id
(键)和Text
(消息)。Text
属性是必需的,并限制为 200 个字符。 - 消息使用实体框架的内存中数据库†存储。
- 应用在其数据库上下文类
AppDbContext
(Data/AppDbContext.cs
) 中包含数据访问层 (DAL)。 - 如果应用启动时数据库为空,则消息存储初始化为三条消息。
- 应用包含只能由经过身份验证的用户访问的
/SecurePage
。
†EF 主题使用 InMemory 进行测试说明如何将内存中数据库用于 MSTest 测试。 本主题使用 xUnit 测试框架。 不同测试框架中的测试概念和测试实现相似,但不完全相同。
尽管应用未使用存储库模式且不是工作单元 (UoW) 模式的有效示例,但 Razor Pages 支持这些开发模式。 有关详细信息,请参阅设计基础结构持久性层和测试控制器逻辑(该示例实现存储库模式)。
测试应用组织
测试应用是 tests/RazorPagesProject.Tests
目录中的控制台应用。
测试应用目录 | 描述 |
| 包含针对以下方面的测试方法:
|
| 包含用于路由和内容类型的测试方法。 |
| 包含使用自定义 |
|
|
测试框架为 xUnit。 使用 Microsoft.AspNetCore.TestHost(包含 TestServer)进行集成测试。 由于 Microsoft.AspNetCore.Mvc.Testing 包用于配置测试主机和测试服务器,因此 TestHost
和 TestServer
包在测试应用的项目文件或测试应用的开发者配置中不需要直接包引用。
集成测试在执行测试前通常需要数据库中的小型数据集。 例如,删除测试需要进行数据库记录删除,因此数据库必须至少有一个记录,删除请求才能成功。
示例应用使用 Utilities.cs
中的三个消息(测试在执行时可以使用它们)设定数据库种子:
C#复制
SUT 的数据库上下文在其 Startup.ConfigureServices
方法中注册。 测试应用的 builder.ConfigureServices
回调在执行应用的 Startup.ConfigureServices
代码之后执行。 若要将不同的数据库用于测试,必须在 builder.ConfigureServices
中替换应用的数据库上下文。 有关详细信息,请参阅自定义 WebApplicationFactory 部分。
对于仍使用 Web 主机的 SUT,测试应用的 builder.ConfigureServices
回调先于 SUT 的 Startup.ConfigureServices
代码。 之后执行测试应用的 builder.ConfigureTestServices
回调。