如何为VB函数中的If-Else分支编写单元测试?
为VB共享函数的If-Else分支编写单元测试的步骤
第一步:先解耦依赖(关键前提)
你的函数里直接New CBasePage创建实例,属于硬编码依赖,单元测试时没法控制IsUIProgressBarFeatureToggleEnabled的返回值,必须先改造代码解耦:
改造方案1:将开关状态作为参数传入
直接把开关状态作为可选参数传给函数,测试时手动控制状态:
Public Shared Function PrependIconForNonApprovedMessage(message As String, Optional title As String = "", Optional isUIProgressBarEnabled As Boolean = False) As String Dim sb As New StringBuilder() If Not isUIProgressBarEnabled Then sb.AppendLine(HeaderUtils.RenderPageTitle(19, title, False, IconId:=String.Format("svg{0}Icon", title.Replace(" ", "")))) Else sb.AppendLine(HeaderUtils.RenderPageTitle(0, title, False, IconId:=String.Format("svg{0}Icon", title.Replace(" ", "")))) End If sb.AppendLine("<br/>") sb.AppendLine(String.Format("<div>{0}</div>", message)) Return sb.ToString() End Function
改造方案2:提取接口注入(更优雅的解耦)
如果CBasePage是自定义类,给它提取一个包含目标属性的接口,让函数接受接口实例:
Public Interface ICBasePage ReadOnly Property IsUIProgressBarFeatureToggleEnabled As Boolean End Interface ' 让CBasePage实现接口 Public Class CBasePage Implements ICBasePage ' 原类的其他逻辑... Public ReadOnly Property IsUIProgressBarFeatureToggleEnabled As Boolean Implements ICBasePage.IsUIProgressBarFeatureToggleEnabled ' 原属性实现 End Property End Class ' 修改后的函数 Public Shared Function PrependIconForNonApprovedMessage(message As String, cb As ICBasePage, Optional title As String = "") As String Dim sb As New StringBuilder() If Not cb.IsUIProgressBarFeatureToggleEnabled Then sb.AppendLine(HeaderUtils.RenderPageTitle(19, title, False, IconId:=String.Format("svg{0}Icon", title.Replace(" ", "")))) Else sb.AppendLine(HeaderUtils.RenderPageTitle(0, title, False, IconId:=String.Format("svg{0}Icon", title.Replace(" ", "")))) End If sb.AppendLine("<br/>") sb.AppendLine(String.Format("<div>{0}</div>", message)) Return sb.ToString() End Function
第二步:编写单元测试(以MSTest为例)
核心是分别测试开关关闭和开关开启两个分支,验证分支逻辑的关键差异(RenderPageTitle的第一个参数是19还是0),以及固定内容的正确性。
测试分支1:功能开关关闭(走If分支)
<TestClass> Public Class MessageRendererTests <TestMethod> Public Sub PrependIconForNonApprovedMessage_WhenProgressBarDisabled_UsesTitleId19() ' 测试数据准备 Dim testMessage = "测试消息内容" Dim testTitle = "审批提醒" ' 方案1调用方式: Dim result = YourClassName.PrependIconForNonApprovedMessage(testMessage, testTitle, isUIProgressBarEnabled:=False) ' 断言关键逻辑:验证是否使用了19作为标题ID(根据RenderPageTitle的实际输出调整断言内容) Assert.IsTrue(result.Contains("title-id='19'")) ' 验证固定内容存在 Assert.IsTrue(result.Contains("<br/>")) Assert.IsTrue(result.Contains($"<div>{testMessage}</div>")) End Sub
测试分支2:功能开关开启(走Else分支)
<TestMethod> Public Sub PrependIconForNonApprovedMessage_WhenProgressBarEnabled_UsesTitleId0() ' 测试数据准备 Dim testMessage = "测试消息内容" Dim testTitle = "审批提醒" ' 方案1调用方式: Dim result = YourClassName.PrependIconForNonApprovedMessage(testMessage, testTitle, isUIProgressBarEnabled:=True) ' 断言关键逻辑:验证是否使用了0作为标题ID Assert.IsTrue(result.Contains("title-id='0'")) ' 验证固定内容存在 Assert.IsTrue(result.Contains("<br/>")) Assert.IsTrue(result.Contains($"<div>{testMessage}</div>")) End Sub End Class
补充说明
- 如果用方案2,可使用Moq(VB版本)模拟
ICBasePage的属性返回值,避免依赖真实类:
Dim mockCb = New Mock(Of ICBasePage)() mockCb.Setup(Function(cb) cb.IsUIProgressBarFeatureToggleEnabled).Returns(True) Dim result = YourClassName.PrependIconForNonApprovedMessage(testMessage, mockCb.Object, testTitle)
- 断言时优先针对分支差异点(19和0),不要过度依赖完整HTML输出,避免UI细节变更导致测试失效。
内容的提问来源于stack exchange,提问作者Gyanendra Pal Singh
相关产品推荐
相关产品推荐

