创建类模拟,而无需调用原始类构造函数

发布于 2025-02-02 12:35:59 字数 1262 浏览 3 评论 0原文

假设我有此代码的库(可以更改的款项)

namespace Library.Namespace;

public interface ISomething { }

internal class Something : ISomething { 
    public Something(...) {
        ...
    }
}

public class Anything {
    private Something _Something;

    public Anything (ISomething something) {
        _Something = (Something) something;
        ...
    }
}

,我想创建的模拟 class:

public MockAnything : Mock<Anything> {
    public MockSomething Something { get; }

    public MockAnything() 
        : this(new MockSomething()) { 
    }

    public MockAnything(MockSomething something) 
        : base(something.Object) {
        Something = something;
    }
}

public MockSomething : Mock<ISomething> {
}

到目前为止,每个人都很好(又名compiller很高兴),但是当运行时im im在调用时会得到异常:

var mock = new MockAnything();

var object = mock.Object; // <-- exception here

System.InvalidCastException 
Unable to cast object of type 'Castle.Proxies.ISomethingProxy' to type 'Library.Namespace.Something'.
  at Library.Namespace.Something..ctor(ISomething something)
  at Castle.Proxies.AnythingProxy..ctor(IInterceptor[] , ISomething something)

任何想法如何正确模拟类,该类别使用构造函数中的直接铸造?

Say i have library with this code (that canot be changed)

namespace Library.Namespace;

public interface ISomething { }

internal class Something : ISomething { 
    public Something(...) {
        ...
    }
}

public class Anything {
    private Something _Something;

    public Anything (ISomething something) {
        _Something = (Something) something;
        ...
    }
}

and i want to create mock of Anything class:

public MockAnything : Mock<Anything> {
    public MockSomething Something { get; }

    public MockAnything() 
        : this(new MockSomething()) { 
    }

    public MockAnything(MockSomething something) 
        : base(something.Object) {
        Something = something;
    }
}

public MockSomething : Mock<ISomething> {
}

everythig good so far (aka compiller is happy), but at runtime im getting exception when calling:

var mock = new MockAnything();

var object = mock.Object; // <-- exception here

System.InvalidCastException 
Unable to cast object of type 'Castle.Proxies.ISomethingProxy' to type 'Library.Namespace.Something'.
  at Library.Namespace.Something..ctor(ISomething something)
  at Castle.Proxies.AnythingProxy..ctor(IInterceptor[] , ISomething something)

any idea how to correctly mock class, that uses direct cast in constructor?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧时光的容颜 2025-02-09 12:36:00

当使用量量时,最好和最简单的方法是基于接口创建模拟。不幸的是,您无法更改库,并在那里添加界面或摆脱演员表(无论如何最好)。

从设计的角度来看,我建议您在库代码周围创建一个包装器,您无法更改。此外,您可以创建一个接口(我们将其称为ianything),其中包含要使用的方法。代替代码中直接使用,而是将ianthing注入代码。以下代码概述了必要的类:

public IInterface IAnything
{
  // Members of the original Anything class that you want to use in your code
}

public class AnythingWrapper : IAnything
{
  private readonly Anything _anything;

  public AnythingWrapper(Anything anything) 
  {
    _anything = anything;
  }

  // IAnything implementation
}

虽然这似乎有些额外的工作,但通常是通过一些粘贴和复制完成的。此外,您可以在代码和库代码之间创建一个抽象。如果库将来更改,则可以在不更改接口的情况下应用包装程序类中的更改。

一旦您创建了界面,就可以轻松创建一个模拟,例如:

var mockAnything = new Mock<IAnything>();

When using Moq, the best and easiest way is to create mocks based on interfaces. Unfortunately, you cannot change the library and add an interface there or get rid of the cast (which would be best anyway).

From a design perspective, I'd recommend to create a wrapper around the library code that you cannot change. In addition, you create an interface (let's call it IAnything) that contains the methods that you want to use. Instead of using Anything directly in your code, you'd inject IAnthing into your code. The following code outlines the necessary classes:

public IInterface IAnything
{
  // Members of the original Anything class that you want to use in your code
}

public class AnythingWrapper : IAnything
{
  private readonly Anything _anything;

  public AnythingWrapper(Anything anything) 
  {
    _anything = anything;
  }

  // IAnything implementation
}

While this might seem like a bit of extra work, it usually is done with some paste-and-copy. In addition, you create a layer of abstraction between your code and the library code. If the library changes in the future, you could be able to apply the changes in your wrapper class without changing the interface as such.

As soon as you have created the interface, you can easily create a mock, e.g.:

var mockAnything = new Mock<IAnything>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文