我有一个代码片段可供模拟,在测试方法中如下所示:
IManager imanager;
public classToBeTested(Manager manager)
{
imanager=manager;
}
public void methodToBeTested()
{
StringBuilder errorString = new StringBuilder();
List<RuleWrapper> allRules;
Dictionary<Guid, RuleConfiguration> allRuleConfigurations;
imanager.LoadAllRules(ref errorString, out allRuleConfigurations, out allRules);
SetGlobalRuleConfigurations(settingsManager, allRuleConfigurations, _globalRuleConfigurations);
}
如何通过设置参数来模拟mock的行为:
我正在尝试实施以下代码段:
public void methodUsedForTesting()
{
StringBuilder errorString = new StringBuilder();
List<Rule> allRules = new List<Rule>();
Dictionary<Guid, RuleConfiguration> allRuleConfigurations = new Dictionary<Guid,RuleConfiguration>();
//Code for Initializing above Data members
RuleConfiguration ruleConfiguration1 = new RuleConfiguration("First");
RuleConfiguration ruleConfiguration2 = new RuleConfiguration("Second");
allRuleConfigurations.Add(ruleConfiguration1);
allRuleConfigurations.Add(ruleConfiguration2);
Rule rule1 = new Rule("First");
Rule rule2 = new Rule("Second");
allRules.add(rule1);
allRules.add(rule2);
Mock<Manager> mockManager = new Mock<Manager>();
mockManager.Setup(p => p.LoadAllRules(ref errorString, out allRuleConfigurations, out allRules));
classToBeTested classtest = new classToBeTested(mockManager.Object);
classtest.methodToBeTested();
}
应该做什么才能让mock返回由我初始化的数据,而不是该特定方法的原始行为?
答案 0 :(得分:1)
要模拟LoadAllRules
,它需要是virtual
,否则您需要模拟界面。设置out
值不是问题,我也不认为它提供了原始行为&#39;方法...我认为你没有得到任何值,因为Setup
找不到匹配。由于ref
参数,它没有找到匹配项。 Moq不支持It.Any
上的ref
匹配...您必须提供相同的对象实例才能匹配。请参阅下面的示例。它配置ref
和不同的out
值。该测试使用xUnit.net和Moq。
public interface IFoo
{
void Bar(ref StringBuilder err, out string val1, out string val2);
}
public class Foo : IFoo
{
public void Bar(ref StringBuilder err, out string val1, out string val2)
{
val1 = "Hello";
val2 = "Howdy";
}
}
public class ClassToBeTested
{
private IFoo _foo;
public StringBuilder Errors = new StringBuilder();
public ClassToBeTested(IFoo foo)
{
_foo = foo;
}
public string MethodToBeTested()
{
string val1, val2;
_foo.Bar(ref Errors, out val1, out val2);
return val1 + " " + val2;
}
}
[Fact]
public void MethodUsedForTesting()
{
var foo = new Mock<IFoo>();
var sut = new ClassToBeTested(foo.Object);
var val1 = "Hi";
var val2 = "Hey";
// the setup for a ref has to be the same object instance
// that is used by MethodToBeTested() ...
// there isn't currently It.Any support for ref parameters
foo.Setup(x => x.Bar(ref sut.Errors, out val1, out val2));
string expected = "Hi Hey";
string actual = sut.MethodToBeTested();
Assert.Equal(expected, actual); // this test passes
}
这是有效的,因为sut.Errors
与MethodToBeTested
内使用的对象相同。在您的示例代码中,情况并非如此......有两个不同的对象,因此不会匹配。
将测试添加到旧系统总是有问题的。 Moq今天无法解决这个问题。您可以查看RhinoMocks which appears to be able to handle ref args。