当有多个 return 的表达式时,如何对方法 return 进行单元测试?
When there are multiple expressions that return, how do you unit test where the method returned?
我想对我的方法进行单元测试,并确保方法 returns 当 condition1 = 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
}
有没有办法知道方法 Consume 返回的确切位置?
当然。
单元测试是一种非常有针对性的测试,用于验证特定场景。在这种情况下,您的场景定义是,您想要验证当 Message 不为 null 且 Confition1 为真时,您的目标方法是由于 condition1 而不是由于 Message null 或 condition2 而返回的。
通过定义场景,我们已经为您的单元测试建立了先决条件。
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 是这里的模拟框架,但它可以是您使用的任何东西。
我想对我的方法进行单元测试,并确保方法 returns 当 condition1 = 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
}
有没有办法知道方法 Consume 返回的确切位置?
当然。
单元测试是一种非常有针对性的测试,用于验证特定场景。在这种情况下,您的场景定义是,您想要验证当 Message 不为 null 且 Confition1 为真时,您的目标方法是由于 condition1 而不是由于 Message null 或 condition2 而返回的。
通过定义场景,我们已经为您的单元测试建立了先决条件。
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 是这里的模拟框架,但它可以是您使用的任何东西。