c# - 如何确定是否调用了包含在 if 语句中的函数?
问题描述
我有一堂课,像这样的:
public class SomeClass: ISomeClass
{
public async Task<ServiceResponse> PerformAction(Context context)
{
if(IsPartner(context))
{
SendTextMessageAsync(context);
}
}
public bool IsPartner(Context context)
{
return SomeStaticHelperClass.GetIsPartner(context.PartnerId);
}
public async void SendTextMessageAsync(Context context)
{
// sends the message
}
}
ISomeClass
公开所有三种方法。
我正在使用起订量,我想编写一个测试来验证
- 当
IsPartner
返回真 - then
SendTextMessage
被调用一次。
我已经尝试了我能想到的一切。
这是我最近的尝试:
public class ReceiptServiceTests
{
[Fact]
public async void SendReceiptsProofsNeededNudgeAsync_ShouldCallSendTextMessageAsync_WhenSessionPartnerIdIsNotNullOrEmptyString()
{
var context = new Context { PartnerId = "12345" };
var mockSomeClass = new Mock<ISomeClass>();
// force IsPartner to return true
mockSomeClass.Setup(m => m.IsPartner(context)).Returns(true);
// call PerformAction which should call SendTextMessageAsync
// because IsPartner will return true
await mockSomeClass.Object.PerformAction(context);
// verify SendTextMessageAsync was actually called
mockSomeClass.Verify(m => m.SendTextMessageAsync(It.IsAny<Context>()), Times.AtLeastOnce);
}
}
我不断收到以下错误:
(预期在模拟上至少调用一次,但从未执行过:m => m.SendTextMessageAsync)
我猜这是因为SendTextMessageAsync
从未调用过。我被困在这里,我不明白如何正确调用它。
我知道这段代码中的一些(或很多)没有意义,为了简洁起见,我已经对其进行了更改。
我真正想弄清楚的是,当函数 (SendTextMessageAsync) 包装在调用另一个返回 true 的函数的if 语句中时,如何确定它是否被调用。
解决方案
正如 rgvlee 已经指出的那样,您只能模拟依赖项并验证它们的方法调用。
在您的情况下SomeStaticHelperClass
,您的依赖项及其GetIsPartner
可以验证的方法。
不幸的是,静态类不是模拟的好选择。如果您可以将该静态类引用替换为接口,那么您将能够轻松地模拟它。
SomeClass
用途IPartnerService
public class SomeClass: ISomeClass
{
private readonly IPartnerService partnerSvc;
public SomeClass(IPartnerService partnerSvc)
{
this.partnerSvc = partnerSvc;
}
public async Task<ServiceResponse> PerformAction(Context context)
{
if(IsPartner(context))
{
SendTextMessageAsync(context);
}
}
public bool IsPartner(Context context)
{
return partnerSvc.GetIsPartner(context.PartnerId);
}
public async void SendTextMessageAsync(Context context)
{
// sends the message
}
}
SomeClass
在单元测试期间使用IPartnerService
模拟
public class ReceiptServiceTests
{
[Fact]
public async Task GivenAPartner_WhenICallPerformAction_ThenItCallsPartnerService()
{
//Arrange
const string partnerId = "12345";
var context = new Context { PartnerId = partnerId };
var partnerSvcMock = new Mock<IPartnerService>();
partnerSvcMock
.Setup(svc => svc.GetIsPartner(partnerId))
.Returns(true);
var SUT = new SomeClass(partnerSvcMock);
//Act
_ = await SUT.PerformAction(context);
//Assert
partnerSvcMock.Verify(svc => svc.GetIsPartner(partnerId), Times.Once);
}
}
推荐阅读
- c# - 带有 GetType 的列表中的代码
- java - 尝试从另一个类 Java Selenium TestNG 调用方法后出现 NullPointerException 错误
- c# - 查询 EF Core 身份角色
- html - 如何使内容获得与容器相同的高度?
- ios - 子视图控制器的视图忽略自动布局约束
- c# - 从值字符串中删除额外的符号
- javascript - 在 React JS 中将值复制到剪贴板而不显示虚拟元素
- reactjs - 使用“npx-create-react-app”创建文件的问题
- angular - 如何在 Angular 应用程序中跨多个时区显示截止日期?
- omnet++ - OMNeT++ 中 inet::Indication* 的 check_and_cast() 错误