我对单元测试完全陌生,我尝试为 crud 操作编写单元测试。我可以为 get by id 和 get all 编写单元测试。但是在为create 和update 编写单元测试时出现了问题。
这是我创建方法的控制器代码
public async Task<IActionResult> Create([FromBody] Message message)
{
var duplicatemessage = await _messageService.DuplicateMessage(message.Text);
if (duplicatemessage == null)
{
_messageService.Create(message);
return CreatedAtRoute("Api", new { id = message.Id.ToString() }, message);
}
else
{
return BadRequest(new { message = "Text Already Exist" });
}
}
这是我为create方法写的单元测试
[TestCase("Hello")]
public async Task Create_StateUnderTest_ExpectedBehavior(Message message)
{
// Arrange
// mockMessageService.Setup(t => t.GetId(id)).ReturnsAsync(new Message());
mockMessageService.Setup(t => t.DuplicateMessage(message.Text)).ReturnsAsync(new Message());
mockMessageService.Setup(t => t.Create(message)).Returns(new Message());
var apiController = this.CreateApiController();
//var message1 = new Message() { Text = "Hello" };
// Act
var result = await apiController.Create(message);
// Assert
Assert.IsInstanceOf<CreatedAtRouteResult>(result);
this.mockRepository.VerifyAll();
}
当我运行测试时出现此错误
留言: System.ArgumentException:“System.String”类型的对象无法转换为“HelloApi.Models.Message”类型。
堆栈跟踪: RuntimeType.TryChangeType(对象值,Binder 绑定器,CultureInfo 文化,布尔需要SpecialCast) RuntimeType.CheckValue(对象值,Binder 绑定器,CultureInfo 文化,BindingFlags invokeAttr) MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfoculture, Signature sig) RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) MethodBase.Invoke(Object obj, Object[] 参数) Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
我尝试调试但未命中调试点。 我试过, Test api CRUD operation with Moq 和 How can I convert an Class Object into String? 这但我认为这与我的问题无关。有谁能帮帮我吗?
答案 0 :(得分:1)
您正在尝试在您的 Api 控制器上测试方法“create”。 所以让我们来看看你的 Api 控制器的依赖关系。 它取决于_messageService,特别是这两个方法-
现在在您的测试用例中,我看到您已经设置了 messageservice 'GetId' 方法的最小起订量,但没有设置上述两个依赖方法。 所以首先你需要设置 'DuplicateMessage' 方法来返回你期望它返回的类型。您可以进行 2 次测试,一个是在它返回 null 时测试 if 块,另一个是在它返回预期值(即不为 null 以测试 else 块)时。
对于如果块测试,您需要为 messageService 上的“创建”方法进行模拟设置。 然后让它返回预期的类型来验证它。
答案 1 :(得分:1)
您需要在构造函数初始化中注入您的模拟服务。像这样的东西。
var apiController = this.CreateApiController(mockMessageService);
答案 2 :(得分:0)
我可以通过这种方式解决问题。
此测试用于创建新消息
这里我采用了两个参数 id 和 Text,并通过使用将其与我的模型类变量 Id 和 Text 相等,
var message = new Message() { Text = Text, Id = id };
[TestCase("Hello", "5fda6c5c49f10b1464f1f2ce")]
public async Task Create_StateUnderTest_ExpectedBehavior(string Text, string id)
{
// Arrange
var message = new Message() { Text = Text, Id = id };
mockMessageService.Setup(t => t.GetId(id)).ReturnsAsync(new Message());
mockMessageService.Setup(t => t.DuplicateMessage(message.Text)).ReturnsAsync(new Message());
mockMessageService.Setup(t => t.Create(message)).Returns(new Message());
var apiController = this.CreateApiController();
var message1 = new Message() { Text = "Hellooo", Id = "5fda6c5c49f10b1464f1f2ca" };
// Act
var result = await apiController.Create(message1);
// Assert
Assert.IsInstanceOf<CreatedAtRouteResult>(result);
this.mockRepository.Verify();
}
所以这里从 testcase 和 message1 传递的值不相等,它不是重复的消息,所以它应该创建一个。因此测试用例是成功的。
此测试用于重复检查
[TestCase("Hello", "5fda6c5c49f10b1464f1f2ce")]
public async Task Create_StateUnderTest_UnExpectedBehavior(string Text, string id)
{
// Arrange
var message = new Message() { Text = Text, Id = id };
mockMessageService.Setup(t => t.GetId(id)).ReturnsAsync(new Message());
mockMessageService.Setup(t => t.Create(message)).Returns(new Message());
mockMessageService.Setup(t => t.DuplicateMessage(message.Text)).ReturnsAsync(new Message());
var apiController = this.CreateApiController();
var message1 = new Message() { Text = "Hello", Id = "5fda6c5c49f10b1464f1f2ce" };
// Act
var result = await apiController.Create(message1);
// Assert
Assert.IsInstanceOf<BadRequestObjectResult>(result);
this.mockRepository.Verify();
}
之前的问题是我传递对象的方式。现在这对我来说很好用。如果我错了,你可以纠正我:) 谢谢大家的帮助!