Dot-Net

如何模擬(使用 Moq)Unity 方法

  • January 23, 2015

擴展方法不適合測試(此處描述:Mocking Extension Methods with Moqhttp ://www.clariusconsulting.net/blogs/kzu/archive/2009/12/22/Howtomockextensionmethods.aspx )。

但是可能有一些模擬 Unity 方法的解決方案?就我而言,我有以下功能:

public class MyManager
{
   public MyManager(IUnityContainer container) : base(container) { }

   public IResult DoJob(IData data)
   {
       IMyLog log = MyContainer.Resolve<IMyLog>();

       ... use log.Id ...

       MyContainer.Resolve<...>();//usage for other purposes...
   }

我想確定“DoJob”方法將始終從容器中獲取“IMyLog”對象,而不是從其他來源……我該如何測試呢?

我最初的想法是改變’DoJob’方法的實現和使用:

IMyLog log = UnityContainer.Resolve(typeof(IMyLog)) as IMyLog;

但是 ‘Resolve(Type t, …)’ 也是一種擴展方法…

歡迎任何想法。

PS 請注意,“我的日誌”對像是在遠離 MyManager.DoJob 的地方創建的…

我知道我遲到了,但我遇到了同樣的問題,並通過模擬以下方法解決了它 -

IUnityContainer.Resolve(Type t, string name, params ResolverOverride[] resolverOverrides);

例如 -

unityMock = new Mock<IUnityContainer>(MockBehavior.Strict);
validatorMock = new Mock<IValidator>(MockBehavior.Strict);
unityMock.Setup(p => p.Resolve(typeof(IValidator), null))
    .Returns(validatorMock.Object);

以防萬一有人需要對此進行模擬並且無法刪除對容器的依賴。

刪除對 IUnityContainer 的依賴,事情變得更容易和更乾淨。相反,讓統一注入您的依賴項,這些依賴項被抽象為介面。這些很容易被嘲笑。這是一個使用 Unity 的小技巧為 IMyLog 注入自動工廠的範例。

public class MyManager
{
  private readonly Func<IMyLog> logFactory;

  public MyManager(Func<IMyLog> logFactory) 
  {
      this.logFactory = logFactory;
  }

  public IResult DoJob(IData data)
  {
      IMyLog log = logFactory();

      ...
  }
}

或者,如果您不需要每次都創建實例:

public class MyManager
{
  private readonly IMyLog myLog;

  public MyManager(IMyLog myLog) 
  {
      this.myLog = myLog;
  }

  public IResult DoJob(IData data)
  {
      ...
  }
}

引用自:https://stackoverflow.com/questions/3791510