【发布时间】:2021-06-03 12:58:36
【问题描述】:
我的问题与我们何时模拟外部资源(在我的情况下,它们是外部 API 和数据库)有关。
假设根据我提供的输入(例如 ID),我希望请求的结果是某个对象的结果。
在测试时,我倾向于使用It.IsAny<int>,而不是写一个真实的 ID,因为我认为它是不必要的,因为它是一个模拟对象,我主要关心的是从该方法返回的内容。
Method of Service.cs
public async IActionResult CreateObject(Guid? objectID){
var response = await myApi.GetObjectFromApi(objectID);
if(!response.IsSuccessStatusCode){
throw new HttpResponseException(response.StatusCode);
}
return Ok(response);
}
测试
[Test]
public void CreateObject_ReturnsSuccess(){
// mocked myApi dependency
_myApiMock
.Setup(x=>x.GetObjectFromApi(It.IsAny<Guid>())
.Returns(new HttpResponseMessage(){ StatusCode = HttpStatusCode.OK }
var response = CreateObject(Guid.Parse("81a130d2-502f-4cf1-a376-63edeb000e9f"));
Assert.That(response.StatusCode, Is.Equal(HttpStatusCode.OK));
}
我的问题是:
由于我在嘲笑 API 依赖项,除了可读性之外,使用实际的 Guid 值还有什么意义吗? (行 -> .Setup(x=>x.GetObjectFromApi(It.IsAny<Guid>()))
【问题讨论】:
-
如果你从不检查你正在测试的代码调用了协作者,你会让自己在以后发现它不是你所期望的。可能不是你传入的那个?
-
不,没关系。如果您要使用
It.Is<Guid>,您可以验证您的依赖函数是否将预期值传递给模拟函数。如果有一些中间操作,它允许您准确验证正在传递的 guid。如果您不在乎,或者您正在控制测试中的值,It.IsAny<Guid>只会验证传递给模拟函数的类型。旁注,该测试是否有效?您是否在某处注入了您的模拟 API? -
感谢您为我澄清! @StiyAle 这不是一个真正的测试,即使它基于我为我正在开发的程序编写的东西。这是一种更好地说明我的困惑的方法。无论如何,非常感谢您为我澄清!
-
这完全取决于你要断言什么。在某些情况下,您可能希望根据检索到的另一个对象检查 ID,以及需要 ID 来验证方法是否真正通过的情况。没有你永远不需要它或你总是需要它。
-
真正重要的是传达了您对正在测试的代码的期望。对我来说,
It.IsAny<Guid>()建议 “我们无法完全控制” - 也许被测试的代码正在创建自己的 GUID,每次都会有所不同。但在这种情况下,您正在传递它,因此如果您将Guid.Parse("81a130d2-502f-4cf1-a376-63edeb000e9f")提取到测试的开头并使用它,很明显您希望通过相同的 GUID。如果不是不是,你会发现的。
标签: c# api unit-testing mocking