【问题标题】:Can not instantiate proxy...Could not find a parameterless constructor无法实例化代理...找不到无参数构造函数
【发布时间】:2021-03-24 23:15:46
【问题描述】:

我正在尝试使用 Moq 创建一个单元测试,以测试 MongoDB.AspNet.Identity V2 提供程序。这条线让我很伤心:

var appUser = new Mock<PreRegistrationMVC.Models.ApplicationUser>();
var userStore = new Mock<MongoDB.AspNet.Identity.UserStore<PreRegistrationMVC.Models.ApplicationUser>>();

似乎 userStore 无法正确实例化,这是错误。

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException was unhandled by user code
  HResult=-2147024809
  Message=Can not instantiate proxy of class: MongoDB.AspNet.Identity.UserStore`1[[MVC.Models.ApplicationUser, MVC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].
Could not find a parameterless constructor.
  Source=Moq
  StackTrace:
       at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
       at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
       at Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments)
       at Moq.Mock`1.<InitializeInstance>b__2()
       at Moq.PexProtector.Invoke(Action action)
       at Moq.Mock`1.InitializeInstance()
       at Moq.Mock`1.OnGetObject()
       at Moq.Mock.GetObject()
       at Moq.Mock.get_Object()
       at Moq.Mock`1.get_Object()
       at MVC_Tests.Identity.Accounts.AccountController_Test.TestSuccessfulRegister() in c:\Users\Tim\Documents\Visual Studio 2013\Projects\PreRegistrationApp\MVC_Tests\Identity\Accounts\AccountController_Test.cs:line 108
  InnerException: 

我对 Moq 完全陌生,所以我正在寻找: Moq 需要什么类型的设置来实例化它? UserStore 类是否存在与 Moq 不兼容的问题?

感谢阅读。

【问题讨论】:

    标签: mongodb moq asp.net-identity


    【解决方案1】:

    MOQ 适用于模拟接口,但不适用于具体类。所以不要模拟具体的类,而是要求接口:

    var userStore = new Mock<IUserStore<PreRegistrationMVC.Models.ApplicationUser>>();
    

    另外ApplicationUser应该是POCO,所以不需要模拟它,只需创建它的实例,没有MOQ并在测试中使用。

    【讨论】:

    • 很好用。还有一件事你能指导我什么是我应该模拟的事情。例如,我正在使用一些层架构,我只想测试一个层,而我想测试它的层也有一些其他层的依赖关系。那么你应该建议什么?
    • @Naveen 你问的是一个非常广泛的话题,而 cmets 不是讨论的最佳场所。我的建议是阅读一本关于单元测试的书——来自 Roy Osherove 的书很好。他详细介绍了您遇到的问题。
    【解决方案2】:

    你可以尝试引用Mock行为,如下图

    Mock<testClass>(MockBehavior.Strict, new object[] {"Hello"}); 
    

    【讨论】:

    • 因为是params参数所以可以写成new Mock&lt;testClass&gt;(MockBehavior.Strict, "Hello");
    【解决方案3】:

    我遇到了这个问题。我写过……

    var x = new Mock<Concrete>();
    

    ...而不是...

    var x = new Mock<IConcrete>();
    

    【讨论】:

      【解决方案4】:

      我知道这是一个迟到的响应,但我一直在寻找答案,但找不到我需要的确切内容,但是在创建模拟时,您可以将参数传递给您想要的构造函数。

      例如,如果您有这样的课程:

      public class Foo
      {
          private readonly Boo _boo;
      
          public Foo(Boo boo)
          {
              _boo = boo;
          }
      }
      

      你可以这样模拟它:

      private readonly Mock<Foo> _foo = new Mock<Foo>(new Mock<Boo>().Object);
      

      【讨论】:

        【解决方案5】:

        为您的 ApplicationUser 类添加一个空构造函数。

        【讨论】:

        • 只需将模拟参数添加到您的模拟构造函数中
        猜你喜欢
        • 2019-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-29
        • 2021-06-07
        • 1970-01-01
        • 1970-01-01
        • 2020-09-15
        相关资源
        最近更新 更多