Moq 框架对 returns 任务的方法进行单元测试
Moq Framework to unit test a method that returns a task
我是这个 MOQ 框架的新手,老实说,我的单元测试很难达到 运行。基本上,我有一个 C# 应用程序,它基本上使用 PostAsync 将一些上传到 APIs。
现在,因为我不能(也不应该)在我的单元测试期间调用 API(否则它将是一个集成测试),我在它周围添加了一个包装器方法并允许该方法通过模拟它来 return true 。但无论我做什么,都是 returning 错误。我已经完成了 SO 问题,但我不确定我错过了什么。我没有使用接口,但正在使用 classes 和虚拟方法。
这是我想要测试的示例代码
public async Task<bool> CreateNoteBookDirectory (string url ,string bearertoken, JavaScriptSerializer jser,RestPostClass rest)
{
NoteBookDirectory jsnbdir = new NoteBookDirectory();
jsnbdir.path = "/JobNotebooks/ClientScoreDataInput";
var directorycreate = jser.Serialize(jsnbdir);
var content = new StringContent(directorycreate, Encoding.UTF8, @"application/json");
bool result=await rest.HttpPost(url, content, bearertoken);
return result;
}
这个方法主要是class.
RestPostClassclass有虚方法HttpPost,其骨架有点像这样
public async virtual Task<bool> HttpPost(String url, StringContent content, string bearertoken)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearertoken);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(@"application/json"));
var postresult = await client.PostAsync(url, content);
bool result = parseResponse(postresult);
return result;
}
现在,在我的单元测试中,我正在尝试测试 CreateNoteBookDirectory 方法,并且由于不想调用 post 方法,因此模拟它。
这是我在示例单元测试中所做的
Mock<DataBricksRestPost> mock = new Mock<DataBricksRestPost>();
mock.Setup(x => x.HttpPost("http://test.com", new StringContent("abc"), "token")).Returns(Task.FromResult(true));
Program prog = new Program();
var jser = new JavaScriptSerializer();
bool result= await prog.CreateNoteBookDirectory("http://test.com", "token", jser, mock.Object);
Assert.IsTrue(result, "Test failed");
它保持 returning 错误,因为显然模拟并没有真正正确地发生。
我错过了什么?
任何问题,我会尽力澄清。
P.S: 我已经使用了现有的 "program" class 因为我基本上是开始。
Mock returns false,因为当你调用 HttpPost
时参数与设置的参数不匹配。第二个参数不同。
您可以像这样设置模拟:
mock
.Setup(x => x.HttpPost("http://test.com", It.IsAny<StringContent>(), "token"))
.Returns(Task.FromResult(true)); //or .ReturnsAsync(true);
它告诉模拟框架,第二个参数可以是 StringContent
类型的任何对象。
可在此处找到文档:https://github.com/Moq/moq4/wiki/Quickstart#matching-arguments
我是这个 MOQ 框架的新手,老实说,我的单元测试很难达到 运行。基本上,我有一个 C# 应用程序,它基本上使用 PostAsync 将一些上传到 APIs。
现在,因为我不能(也不应该)在我的单元测试期间调用 API(否则它将是一个集成测试),我在它周围添加了一个包装器方法并允许该方法通过模拟它来 return true 。但无论我做什么,都是 returning 错误。我已经完成了 SO 问题,但我不确定我错过了什么。我没有使用接口,但正在使用 classes 和虚拟方法。
这是我想要测试的示例代码
public async Task<bool> CreateNoteBookDirectory (string url ,string bearertoken, JavaScriptSerializer jser,RestPostClass rest)
{
NoteBookDirectory jsnbdir = new NoteBookDirectory();
jsnbdir.path = "/JobNotebooks/ClientScoreDataInput";
var directorycreate = jser.Serialize(jsnbdir);
var content = new StringContent(directorycreate, Encoding.UTF8, @"application/json");
bool result=await rest.HttpPost(url, content, bearertoken);
return result;
}
这个方法主要是class.
RestPostClassclass有虚方法HttpPost,其骨架有点像这样
public async virtual Task<bool> HttpPost(String url, StringContent content, string bearertoken)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearertoken);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(@"application/json"));
var postresult = await client.PostAsync(url, content);
bool result = parseResponse(postresult);
return result;
}
现在,在我的单元测试中,我正在尝试测试 CreateNoteBookDirectory 方法,并且由于不想调用 post 方法,因此模拟它。
这是我在示例单元测试中所做的
Mock<DataBricksRestPost> mock = new Mock<DataBricksRestPost>();
mock.Setup(x => x.HttpPost("http://test.com", new StringContent("abc"), "token")).Returns(Task.FromResult(true));
Program prog = new Program();
var jser = new JavaScriptSerializer();
bool result= await prog.CreateNoteBookDirectory("http://test.com", "token", jser, mock.Object);
Assert.IsTrue(result, "Test failed");
它保持 returning 错误,因为显然模拟并没有真正正确地发生。
我错过了什么?
任何问题,我会尽力澄清。
P.S: 我已经使用了现有的 "program" class 因为我基本上是开始。
Mock returns false,因为当你调用 HttpPost
时参数与设置的参数不匹配。第二个参数不同。
您可以像这样设置模拟:
mock
.Setup(x => x.HttpPost("http://test.com", It.IsAny<StringContent>(), "token"))
.Returns(Task.FromResult(true)); //or .ReturnsAsync(true);
它告诉模拟框架,第二个参数可以是 StringContent
类型的任何对象。
可在此处找到文档:https://github.com/Moq/moq4/wiki/Quickstart#matching-arguments