当有多个表达式返回时,如何单元测试方法返回的位置

本文关键字:返回 单元 位置 测试方法 何单元 表达式 | 更新日期: 2023-09-27 18:37:04

我想对我的方法进行单元测试,并确保该方法在条件 1 = true 时返回:

public bool condition1{get;set;}
public bool condition2{get;set;}
public void Consume(IConsumeContext<mymessage> context)
{
    if (context.Message==null)
    {
        Logme("No message");
        return;
    }
    if (condition1)
    {
        Logme("condition1 is true");
        return;
    }
    if (condition2)
    {
        Logme("condition2 is true");
        return;
    }
    //do work
}

有没有办法知道消耗方法返回的确切位置?

当有多个表达式返回时,如何单元测试方法返回的位置

当然。

单元测试是一种非常有针对性的测试,用于验证特定方案。在本例中,您的方案定义是,您希望验证当 Message 不为 null 且 Confition1 为 true 时,目标方法是否由于条件 1 而返回,而不是由于消息 null 或条件 2。

通过定义方案,我们已经为您的单元测试建立了先决条件。

IConsumeContext<mymessage> contextMock = new Mock<IConsumeContext<mymessage>>();
contextMock.Setup(c => c.Message).Returns("Not_A_Null_Value");
var obj = new UberConsumer();
obj.Condition1 = true;
// obj.Condition2 doesn't really matter.. so you could run a combination of the tests, 
// one for condition2 = true and another for false.

现在是最重要的部分。 要验证您的目标代码是否由于 Condition1 而返回,您需要再做一件事:

能够验证此调用是否确实由目标代码进行,并且是对 LogMe 的唯一调用。

 Logme("condition1 is true");

最好的方法是模拟此方法,或者如果它不可模拟,则将其抽象到接口中并模拟出来。 如果它是一个简单的无害方法,只是将字符串分配给一个变量,你可以断言该变量。 让我们假设它是一个可模拟的方法。

所以你的测试看起来像这样。

// arrange
IConsumeContext<mymessage> contextMock = new Mock<IConsumeContext<mymessage>>();
contextMock.Setup(c => c.Message).Returns("Not_A_Null_Value");
var obj = new UberConsumer();
obj.Condition1 = true;
// obj.Condition2 doesn't really matter.. so you could run a combination of the tests, 
// one for condition2 = true and another for false.
// setup callback for the mockable LogMe method and capture the string parameter value
   // string capturedStringValue = null
   // mockLogMeObj.Setup(l => l.LogMe(It.IsAny<string>()).Callback(val => { capturedStringValue = val} );
   // you could also verify the call count
// act
uberConsume.Consume(contextMock.Object);
// assert
// assert that the captured parameter of Logme was "condition1 is true"
Assert.Equals("condition1 is true", capturedStringValue);
// assert that the LogMe was called only once.
//  mockLogMeObj.Setup(l => l.LogMe(It.IsAny<string>()).Verify(Times.Once());

这为您提供了对要验证的确切内容的最佳验证。

我假设 Moq 是这里的模拟框架,但它可以是你正在使用的任何东西。