Moq,具有构造函数依赖关系的调用库
本文关键字:关系 调用 函数依赖 Moq | 更新日期: 2023-09-27 18:20:48
我有一个类
public class Foo
{
public Foo(IBar bar)
{
//...
}
public virtual int GetValue(){}
public virtual DoActual()
{
...
var value = GetValue();
...
}
}
我需要测试它。我想覆盖GetValue方法并将特定值返回给调用者。这是我的测试代码:
[TestMethod]
public void Test()
{
var mock = new Mock<Foo>{ CallBase=true}; // problem is here
mock.Setup(x=>x.GetValue()).Returns(1);
mock.DoActual();
//asserts
}
由于我的Foo类构造函数有依赖项,所以我必须将它传递到对象初始值设定项中。Moq提供将参数传递给params[]重载:
[TestMethod]
public void Test()
{
var barMock= new Mock<IBar>();
var mock = new Mock<Foo>(barMock){ CallBase=true}; // problem is still here
mock.Setup(x=>x.GetValue()).Returns(1);
mock.DoActual();
//asserts
}
当我以这种方式传递mock时,我错误地说Moq.mock`1[IBar]不是Foo-accepting的构造函数。
当我把barMock.Object传递给构造函数时,我得到了基本相同的错误,但类型不同:
"Could not find a constructor that would match given arguments:
Castle.Proxies.IBarProxy"
我被困在这个地方,不知道如何解决我的Foo类依赖关系。
您上面最小化的问题没有编译,这表明您没有以当前形式对其进行测试。这使得很难判断您的实际问题是否被正确描述,或者您是否将问题减少得太多并删除了实际问题,在这种情况下,您可能需要编辑您的问题以包含更多详细信息。下面的代码,基于上面的编译和工作。
public interface IBar {
}
public class Foo
{
public Foo(IBar bar)
{
//...
}
public virtual int GetValue(){ return 0;}
public virtual void DoActual()
{
var value = GetValue();
}
}
[TestFixture]
public class SomeTests {
[Test]
public void TestMethodCalled() {
var barMock = new Mock<IBar>();
var mock = new Mock<Foo>(barMock.Object) { CallBase = true };
mock.Setup(x => x.GetValue()).Returns(1);
mock.Object.DoActual();
//asserts
mock.Verify(x => x.GetValue());
}
}
它将barMock.Object
传递到构造函数中,并验证该方法是否已被调用。
如前所述,模拟您正在测试的类通常是个坏主意,更好的方法是操作/模拟GetValue
的依赖关系,以便它返回您想要的结果。显然,您的能力将取决于该方法的作用,以及在必要时可以更改多少代码,有时,尤其是对于遗留代码,您只需要使用现有的代码。
通常,您应该创建要测试的类(测试中的系统,SUT)的依赖项的mock,而不是SUT本身。
我建议创建以下
public class FooForTest : Foo
{
public FooForTest(IBar bar) : base(bar) {}
public override int GetValue() { return 1; }
}
那么new FooForTest(barMock.Object)
应该起作用。