是否可以使用 Moq(3.0+)分配 out
/ref
参数?
我已经尝试过使用 Callback()
,但是因为它基于泛型,所以 Action<>
不支持 ref 参数。我还想在 ref
参数的输入上加上一个约束(It.Is
),尽管我可以在回调函数中实现这一点。
我知道 Rhino Mocks 支持这个功能,但我们的项目已经在使用 Moq 了。
是否可以使用 Moq(3.0+)分配 out
/ref
参数?
我已经尝试过使用 Callback()
,但是因为它基于泛型,所以 Action<>
不支持 ref 参数。我还想在 ref
参数的输入上加上一个约束(It.Is
),尽管我可以在回调函数中实现这一点。
我知道 Rhino Mocks 支持这个功能,但我们的项目已经在使用 Moq 了。
在我简单地创建一个实现你试图模拟的任何接口的新“Fake”类的实例之前,我曾经为这里的许多建议而苦苦挣扎。然后,你可以使用方法本身设置输出参数的值。
[Fact]
public void DeclineLowIncomeApplicationsOutDemo()
{
var mockValidator = new Mock<IFrequentFlyerNumberValidator>();
var isValid = true; // Whatever we set here, thats what we will get.
mockValidator.Setup(x => x.IsValid(It.IsAny<string>(), out isValid));
var sut = new CreditCardApplicationEvaluator(mockValidator.Object);
var application = new CreditCardApplication
{
GrossAnnualIncome = 19_999,
Age = 42
};
var decision = sut.EvaluateUsingOut(application);
Assert.Equal(CreditCardApplicationDecision.AutoDeclined, decision);
}
public interface IFrequentFlyerNumberValidator
{
bool IsValid(string frequentFlyerNumber);
void IsValid(string frequentFlyerNumber, out bool isValid);
}
[Test]
public void TestForOutParameterInMoq()
{
//Arrange
_mockParameterManager= new Mock<IParameterManager>();
Mock<IParameter > mockParameter= new Mock<IParameter >();
//Parameter affectation should be useless but is not. It's really used by Moq
IParameter parameter= mockParameter.Object;
//Mock method used in UpperParameterManager
_mockParameterManager.Setup(x => x.OutMethod(out parameter));
//Act with the real instance
_UpperParameterManager.UpperOutMethod(out parameter);
//Assert that method used on the out parameter of inner out method are really called
mockParameter.Verify(x => x.FunctionCalledInOutMethodAfterInnerOutMethod(),Times.Once());
}
类似这样就可以解决问题:
需要被模拟的方法是
public bool GenerateClient(out Client client);
那么模拟部分将会是:
Client client = new Client();
clintMockBll
.Setup(x => x.GenerateClient(out client))
.Returns((Client client1) =>
{
client = new Client(){Name="Something"};
return true;
});
对于希望使用 It.IsAny
作为输出参数的人,这是对 Craig Celeste 答案的改进:
public interface IService
{
void DoSomething(out string a);
}
[TestMethod]
public void Test()
{
var service = GetService();
string actualValue;
service.Object.DoSomething(out actualValue);
Assert.AreEqual(expectedValue, actualValue);
}
private IService GetService()
{
var service = new Mock<IService>();
var anyString = It.IsAny<string>();
service.Setup(s => s.DoSomething(out anyString))
.Callback((out string providedString) =>
{
providedString = "SomeValue";
});
return service.Object;
}
如果您的方法还需要返回一些内容,您也可以使用Returns
而不是Callback
。
It.IsAny<T>()
类似的匹配器 (ref It.Ref<T>.IsAny
) 到支持通过自定义委托类型匹配方法签名来设置.Callback()
和.Returns()
。同样支持受保护的方法。请参见例如下面 我的回答。 - stakx - no longer contributing