moq只有一个类中的一个方法

use*_*335 16 c# moq

我正在使用moq.dll当我模拟一个类(所有的IRepository接口)时,我使用这个行代码

   int state = 5;
   var rep = new Mock<IRepository>();
   rep.Setup(x => x.SaveState(state)).Returns(true);
   IRepository repository = rep.Object;
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我模拟了存储库类中的所有函数.然后,类库中的所有方法都被Mock dll的方法设置所取代

我想使用类库中定义的所有方法(真正的类)并且只模拟一个函数(SaveState)

我怎样才能做到这一点?有可能吗?

Stu*_*tLC 24

您可以创建真实存储库的实例,然后使用它As<>()来获取所需的接口,然后可以使用设置覆盖,如下所示:

var mockRep = new Mock<RealRepository>(ctorArg1, ctorArg2, ...)
                     .As<IRepository>();
mockRep.Setup(x => x.SaveState(state)).Returns(true);
Run Code Online (Sandbox Code Playgroud)

然后mockRep.Object作为存储库依赖于被测试的类.请注意,您只能Interface以这种方式对*或虚拟方法进行Mock方法.

更新:*这可能不适用于所有方案,因为.Setup它只适用于方法,而C#接口实现是"虚拟"并 默认密封.并且使用As()将阻止部分模拟行为.

因此,RealRepository具体类似乎 需要IRepository使用虚方法实现接口,以便部分模拟成功,在这种情况下CallBase可以用于连接.

   public interface IRepo
   {
      string Foo();
      string Bar();
   }

   public class RealRepo : IRepo
   {
      public RealRepo(string p1, string p2) {Console.WriteLine("CTOR : {0} {1}", p1, p2); }
      // ** These need to be virtual in order for the partial mock Setups
      public virtual string Foo() { return "RealFoo"; }
      public virtual string Bar() {return "RealBar"; }
   }

   public class Sut
   {
      private readonly IRepo _repo;
      public Sut(IRepo repo) { _repo = repo; }

      public void DoFooBar()
      {
         Console.WriteLine(_repo.Foo());
         Console.WriteLine(_repo.Bar());
      }
   }


   [TestFixture]
   public class SomeFixture
   {
      [Test]
      public void SomeTest()
      {
        var mockRepo = new Mock<RealRepo>("1st Param", "2nd Param");
        // For the partially mocked methods
        mockRepo.Setup(mr => mr.Foo())
           .Returns("MockedFoo");
        // To wireup the concrete class.
        mockRepo.CallBase = true;
        var sut = new Sut(mockRepo.Object);
        sut.DoFooBar();
      }
   }
Run Code Online (Sandbox Code Playgroud)