提问者:小点点

使用具有默认参数值的构造函数模拟类的受保护成员


我知道测试非公共成员被认为是不好的,但为什么这不起作用?它抛出ArgumentException并带有消息:成员Connect不存在

public class FtpHelper : IFtpHelper
{
   public FtpHelper(ISignalRLogger signalRLogger, IDirectoryWrap directoryWrap = null) {
    ... some code
   }

   protected virtual IFtpClient Connect(string ftpPath) {
     ... some code
   }
}

public class TestFtpHelper
{
   [Fact]
   public void Calls_connect(){

      var signalrMq = new Mock<ISignalRLogger>();
      var clientMq = new Mock<FtpHelper>(
            MockBehavior.Strict, new { signalRLogger = signalrMq.Object });

      clientMq.Protected().Setup<IFtpClient>("Connect",new { ftpPath = ""})
    .Returns(It.IsAny<IFtpClient>()); // That doesn't work

   }
}

UPD:哦,我注意到即使在最后一行之前,当它初始化clientMq并且我尝试使用clientMq. Object时,它也会抛出异常,并带有以下消息:在mocked类型上没有找到给定参数的匹配构造函数。我想这与默认值的奇怪构造函数有关


共2个答案

匿名用户

您需要以下附加设置
1。使用Moq. Protted()在顶部添加
2。使用InternalsVisibleTo属性使类型对Moq可见。[汇编:InternalsVisibleTo(RhinoMocks.NormalName)][汇编:InternalsVisibleTo(RhinoMocks.StrongName)]

从链接

匿名用户

我知道怎么了…
这个:

var clientMq = new Mock<FtpHelper>(
            MockBehavior.Strict, new { signalRLogger = signalrMq.Object });

应该是:

var clientMq = new Mock<FtpHelper>(
            MockBehavior.Strict, signalrMq.Object);

签名是params对象[]

但是现在它抛出了NullRecentceException

upd:你试图模拟的成员不仅应该是虚拟的,而且应该是内部的。仅仅让它们“受保护”是不够的。代理不能通过Refection. Emit()来识别,Moq使用它/