gpt4 book ai didi

c# - Azure 持久 HTTPStart 方法中的单元测试 (Rhino) DBUp

转载 作者:行者123 更新时间:2023-11-30 21:32:39 25 4
gpt4 key购买 nike

技术栈

  1. 用于数据库升级的 DBUP
  2. 用于事件的 Azure Durable
  3. Rhino 模拟单元测试。

情况

目前,我已将我的数据库升级 (DBUp) 语句放在 HTTPStart 方法中,作为我的持久 azure 函数的入口点。

DeployChanges.To
.SqlDatabase(connectionString)
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
.LogToConsole()
.Build();

问题

这种方法的问题是 DBUp 使用静态类来升级数据库,而我不能使用 Rhino 来模拟静态类上的方法。

问题

我想将 DBUp 部分包装在一个非静态类中,但随后我需要模拟构造函数初始化。不确定这是否可行

代码 - 升级数据库的助手类

public class DBUPHelper
{
public bool UpgradeDB()
{
bool status = true;
var connectionString = "Data Source=localhost;Initial Catalog=master;Integrated Security=True;Connect Timeout=15";
var upgrader =
DeployChanges.To
.SqlDatabase(connectionString)
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
.LogToConsole()
.Build();

var result = upgrader.PerformUpgrade();

if (!result.Successful)
{
status = false;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(result.Error);
Console.ResetColor();
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Success!");
Console.ResetColor();
return status;
}
}

代码 - 调用 Helper 类的 HTTPStart 方法

private static ILogger logObj;
[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
[OrchestrationClient] DurableOrchestrationClientBase starter,
string functionName,
ILogger log, ExecutionContext context)
{
HttpResponseMessage response = null;
var config = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Helper.Helper helper = new Helper.Helper(config.GetConnectionString("ConnString"););
if (helper.UpgradeDB())
{
log.LogInformation("DB Upgraded Successfully");
logObj = log;
try
{
var provider = new MultipartMemoryStreamProvider();
await req.Content.ReadAsMultipartAsync(provider);
Application policy = await GeneratePolicyObject(provider);
string instanceId = await starter.StartNewAsync(functionName, policy);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
response = starter.CreateCheckStatusResponse(req, instanceId);
response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(10));
}
catch (Exception ex)
{
response = new HttpResponseMessage();
log.LogCritical(ex.ToString());
log.LogCritical(ex.InnerException.ToString());
log.LogCritical(ex.StackTrace);
response.Content = new StringContent(ex.ToString());
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
}
}
else log.LogCritical("DB Upgrade Failed. Check logs for exception");
return response;
}

enter image description here

查看突出显示的区域。我想模拟构造函数初始化,以便在单元测试时不会发生数据库调用。

谁能帮忙,拜托。

问候塔伦

最佳答案

使用抽象来避免与实现问题的紧密耦合。

public interface IDBHelper {
bool UpgradeDB();
}

public class DBUPHelper: IDBHelper {
//...code omitted for brevity
}

此外,由于被测方法是静态的,因此会公开静态字段/属性

public static class MyFunction {
//At run time this will use default helper
public static IDBHelper Helper = new DBUPHelper();

private static ILogger logObj;
[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
[OrchestrationClient] DurableOrchestrationClientBase starter,
string functionName,
ILogger log, ExecutionContext context)
{
HttpResponseMessage response = null;
if (helper.UpgradeDB()) {
log.LogInformation("DB Upgraded Successfully");
logObj = log;
try
{
var provider = new MultipartMemoryStreamProvider();
await req.Content.ReadAsMultipartAsync(provider);
Application policy = await GeneratePolicyObject(provider);
string instanceId = await starter.StartNewAsync(functionName, policy);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
response = starter.CreateCheckStatusResponse(req, instanceId);
response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(10));
}
catch (Exception ex)
{
response = new HttpResponseMessage();
log.LogCritical(ex.ToString());
log.LogCritical(ex.InnerException.ToString());
log.LogCritical(ex.StackTrace);
response.Content = new StringContent(ex.ToString());
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
}
}
else log.LogCritical("DB Upgrade Failed. Check logs for exception");
return response;
}
}

单独测试时可以替换

public async Task TestFunction {
//Arrange
var helper = MockRepository.GenerateMock<IDBHelper>();
MyFunction.helper = helper; //<<--override default helper with mock
helper.Stub(_ => _.UpgradeDB()).Return(false);//or true is that is what you desire

//...arrange other parameters / dependencies

//Act
var actual = await MyFunction.Run(...);

//Assert
//...
}

关于c# - Azure 持久 HTTPStart 方法中的单元测试 (Rhino) DBUp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52157361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com