我写了一个azure函数v1 HttpTrigger,它从我们的api服务获取客户端详细信息和交易,只有一个参数“ frequency”,它也是可选的,因此当触发该函数时,它将获取详细信息然后获取交易对于每个零售商的详细信息并返回每个零售商的交易费用列表,我想为我的功能编写一个单元测试,但是我看不到适合我的方案的示例,有人可以给我一个示例单元测试(含moq ,如果可能的话),这是函数代码库示例:
[FunctionName("FunctionTest1")]
public static async Task<HttpResponseMessage>
Run([HttpTrigger(AuthorizationLevel.Function)]HttpRequestMessage req, ILogger log) {
log.LogInformation("C# HTTP trigger function processed a request.");
#region Properties
string Frequency = req.GetQueryNameValuePairs().FirstOrDefault(q => string.Compare(q.Key, "frequency", true) == 0).Value;
#endregion
log.LogInformation("Getting client details from MongoDB");
Process of Getting ClientDetails
log.LogInformation("Get and compute Transaction Fee foreach retailers from client details");
Process of Getting And Computing Transactions for each retailers (NOTE Took too much time)
log.LogInformation("Return results response");
return txnList == null
? new HttpResponseMessage(HttpStatusCode.InternalServerError) {
Content = new StringContent(JsonConvert.SerializeObject("Error getting data from server"), Encoding.UTF8, "application/json")
} : new HttpResponseMessage(HttpStatusCode.OK) {
Content = new StringContent(JsonConvert.SerializeObject(txnList, Newtonsoft.Json.Formatting.Indented), Encoding.UTF8, "application/json")
};
}
我尝试过的单元测试参考:https://docs.microsoft.com/en-us/azure/azure-functions/functions-test-a-function
https://medium.com/@tsuyoshiushio/writing-unit-test-for-azure-durable-functions-80f2af07c65e
我尝试过的事情:
[TestMethod]
public async Task Response_Should_Not_Null()
{
var request = new HttpRequestMessage();
var logger = Mock.Of<ILogger>();
var response = await FunctionTest1.Run(request, logger).ConfigureAwait(false);
Assert.IsNotNull(response);
}
我遇到的错误:
线程0x5580已退出,代码为0(0x0)。
程序“ [23748] dotnet.exe”已退出,代码为0(0x0)。
程序“ [23748] dotnet.exe:程序跟踪”已退出,代码为0(0x0)。
致谢,
尼科
答案 0 :(得分:1)
在这里,我将提供带有辅助功能的样本单元测试用例。
测试用例:-Request_With_Query 辅助功能:-HttpReuqestSetup(通过删除HttprequestObject)
我注意到嘲笑了logger对象,因为它可以帮助我提供有用的信息
这就是我的功能的样子
<?php $p3=1;$posts=mysql_query("select * from provinces INNER JOIN posts ON posts.id_province=provinces.id_province");
while($ps3=mysql_fetch_array($posts)){
$jdlpost=$ps3[nm_news];
$despost=$ps3[desc];
$jdlprovince=$ps3[nm_province];
$link3=$_COOKIE[linkmenu].$ps3['id_news']."/"."news/".linktitle($ps3['nm_news']);
if($p3===1){
echo "<div class=modal fade in' id='tc$ps3[id_news]> <div class=modal-dialog modal-lg> <div class='modal-content' style= 'margin-top: 100px;'>"
."<div class='modal-header'>"
."<h5 class='modal-title' id='exampleModalLabel'>$jdlprovince</h5>
<button type='button' class='close' data-dismiss='modal' aria-label='Close'>
<span aria-hidden='true'>×</span>
</button>"
."</div>"
."<div class='modal-body'>"
."<div class='row'>"
."<div class='col-md-12'>"
."<div class='box-list'>"
."<div class='detailgeo dg3 tampil$ps3[id_news] active view view-tenth'>"
."<div class='coverhover'><div class='imgs' style='background-image:url(".$_COOKIE[config]."dynamic/200/imgnews/".$ps3[pict].")'> </div>
<div class='mask'>
<a href='$link3' class='info' title='$jdlpost'><i class='fa fa-search'></i></a>
</div>
</div>"
."<div class='ise'><b><a href='$link3'>$jdlpost</a></b><i>".ucfirst(textlimit(rmSpecialChars(cleanHTML($despost)),180))."</i><div class='clear'></div><a href='$link3'class='remor' class='remor'>READ MORE <i class='fa fa-chevron-right'></i></a></div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>";
}else{
echo "<div class=modal fade in' id='tc$ps3[id_news]> <div class=modal-dialog modal-lg> <div class='modal-content' style= 'margin-top: 100px;'>"
<div class='modal-content' style= 'margin-top: 100px;'>"
."<div class='modal-header'>"
."<h5 class='modal-title' id='exampleModalLabel'>$jdlprovince</h5>
<button type='button' class='close' data-dismiss='modal' aria-label='Close'>
<span aria-hidden='true'>×</span>
</button>"
."</div>"
."<div class='modal-body'>"
."<div class='row'>"
."<div class='col-md-12'>"
."<div class='box-list'>"
."<div class='detailgeo dg3 tampil$ps3[id_news] active view view-tenth'>"
."<div class='coverhover'><div class='imgs' style='background-image:url(".$_COOKIE[config]."dynamic/200/imgnews/".$ps3[pict].")'> </div>
<div class='mask'>
<a href='$link3' class='info' title='$jdlpost'><i class='fa fa-search'></i></a>
</div>
</div>"
."<div class='ise'><b><a href='$link3'>$jdlpost</a></b><i>".ucfirst(textlimit(rmSpecialChars(cleanHTML($despost)),180))."</i><div class='clear'></div><a href='$link3'class='remor' class='remor'>READ MORE <i class='fa fa-chevron-right'></i></a></div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>"
."</div>";
}?>
<?php
?>
<script>
$(document).ready(function(){
$(".maps<?php echo $ps3['id_news'];?>").click(function(){
$(".dg3").removeClass("active");
$(".tthree .posisi").removeClass("active");
$(this).addClass("active");
$(".tampil<?php echo $ps3['id_news'];?>").addClass("active");
});
});
</script><?php
$p3++;
}
?>
这是我的测试类的样子:
public static class HttpTrigger
{
[FunctionName("HttpTrigger")]
public async static Task<IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = new StreamReader(req.Body).ReadToEnd();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
这是助手类
使用Microsoft.AspNetCore.Http; 使用Microsoft.AspNetCore.Http.Internal; 使用Microsoft.Azure.WebJobs; 使用Microsoft.Azure.WebJobs.Host; 使用Microsoft.Extensions.Primitives; 使用Moq; 使用系统; 使用System.Collections.Generic; 使用System.IO; 使用System.Net.Http; 使用System.Text; 使用System.Threading; 使用System.Threading.Tasks;
[TestClass]
public class HttpTriggerTest : FunctionTestHelper.FunctionTest
{
[TestMethod]
public async Task Request_With_Query()
{
var query = new Dictionary<String, StringValues>();
query.TryAdd("name", "ushio");
var body = "";
var result = await HttpTrigger.RunAsync(req: HttpRequestSetup(query, body), log: log);
var resultObject = (OkObjectResult)result;
Assert.AreEqual("Hello, ushio", resultObject.Value);
}
[TestMethod]
public async Task Request_Without_Query()
{
var query = new Dictionary<String, StringValues>();
var body = "{\"name\":\"yamada\"}";
var result = await HttpTrigger.RunAsync(HttpRequestSetup(query, body), log);
var resultObject = (OkObjectResult)result;
Assert.AreEqual("Hello, yamada", resultObject.Value);
}
[TestMethod]
public async Task Request_Without_Query_And_Body()
{
var query = new Dictionary<String, StringValues>();
var body = "";
var result = await HttpTrigger.RunAsync(HttpRequestSetup(query, body), log);
var resultObject = (BadRequestObjectResult)result;
Assert.AreEqual("Please pass a name on the query string or in the request body", resultObject.Value);
}
}
在您的情况下使用类似的模式,您应该能够和平地模拟和编写UT。
希望有帮助。