c# - 如何为使用包装器的 Azure Functions 编写单元测试?
问题描述
我在所有 Azure Functions 上都使用了一个包装类:
public interface IFunctionWrapper
{
Task<IActionResult> Execute(HttpRequest req, ExecutionContext context, Func<Task<IActionResult>> azureFunction);
}
public class FunctionWrapper : IFunctionWrapper
{
private readonly ILogger _log;
public FunctionWrapper(ILogger<FunctionWrapper> log)
{
_log = log;
}
public async Task<IActionResult> Execute(HttpRequest req, ExecutionContext context, Func<Task<IActionResult>> azureFunction)
{
try
{
// Log few extra information to Application Insights
// Do authentication
return await azureFunction();
}
catch (Exception ex)
{
// Return a custom error response
}
}
}
以下是它在函数中的使用方式:
public class MyFunctions
{
private readonly IFunctionWrapper _functionWrapper;
public MyFunctions(IFunctionWrapper functionWrapper)
{
_functionWrapper = functionWrapper;
}
public async Task<IActionResult> GetPost(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
ExecutionContext context,
ILogger log)
{
return await _functionWrapper.Execute(req, context, async () =>
{
// Function code...
return new JsonResult(post);
});
}
}
我正在尝试为此 GetPost 函数编写单元测试。在这种情况下如何模拟 FunctionWrapper 类?
解决方案
模拟包装抽象的期望行为。
以下示例使用 MOQ 来模拟包装器。注意mock的设置
[TestClass]
public class MyFunctionsTests {
[TestMethod]
public async Task GetPost_Should_Execute_Wrapper() {
//Arrange
//mock the wrapper
IFunctionWrapper wrapper = Mock.Of<IFunctionWrapper>();
//configure the mocked wrapper to behave as expected when invoked
Mock.Get(wrapper)
.Setup(_ => _.Execute(It.IsAny<HttpRequest>(), It.IsAny<ExecutionContext>(), It.IsAny<Func<Task<IActionResult>>>()))
.Returns((HttpRequest r, ExecutionContext c, Func<Task<IActionResult>> azureFunction) =>
azureFunction()); //<-- invokes the delegate and returns its result
MyFunctions function = new MyFunctions(wrapper);
//these should be initialized as needed for the test
HttpRequest req = null;
ExecutionContext ctx = null;
ILogger log = Mock.Of<ILogger>();
//Act
IActionResult result = await function.GetPost(req, ctx, log);
//Assert
result.Should().NotBeNull();
//verify that mocked wrapper was called
Mock.Get(wrapper).Verify(_ => _.Execute(It.IsAny<HttpRequest>(), It.IsAny<ExecutionContext>(), It.IsAny<Func<Task<IActionResult>>>()));
//...perform other assertions here
}
}
原始问题中的代码省略了被测对象的大部分正文。话虽如此,这个例子是基于最初提供的,它被用来创建一个可重现的例子,用于创建上面的测试
推荐阅读
- mysql - 如果您正在更新密钥,如何将 INSERT INTO ON DUPLICATE KEY UPDATE 转换为多个查询
- swift - 以编程方式将 NSTableView 绑定到 NSArrayController
- node.js - 在 Spring Boot 控制器中压缩响应并在 JavaScript 中膨胀
- ruby - 测试环境中 Rails.application.secrets 中缺少 secret_key_base
- javascript - Titanium Appcelerator - 在文本字段中输入出生日期
- python-2.7 - 在瓶中的 Web 应用程序中设置应用程序根目录
- python - 保存并打开字典
- mysql - 使用 2 个分组函数从 MySQL 获取平均值
- bash - BASH 脚本 - 子菜单和嵌套案例
- r - 使用 runGdal 下载 MODIS 图像时出错