使用密封具体类对第三方 API 进行单元测试
刚开始 TDD,一切都很顺利,直到我遇到了这堵砖墙。
我正在围绕第三方 API 编写一个外观。该 API 非常好,因为所有内容都可以通过接口访问,因此在测试我的外观时很容易被模拟。
整个 API 是通过根接口访问的,并且您可以从中深入了解接口的深层层次结构。我的外观在标准 IoC 实践中在其构造函数中采用了这个根接口。
TDD 进展顺利,但使用深层接口时模拟变得有点复杂,因为我必须模拟整个接口树,所以有点痛苦。不过没什么大不了的,我只是维护了一个构建模拟的辅助函数。但这确实让我想知道我是否使用了正确的方法。
不管怎样,在树的中间,我突然遇到了一个密封的混凝土类型,没有公共构造函数,所以我无法嘲笑它。这导致我的测试失败,因为模拟的 API 总是为此成员返回 null。
我能看到的唯一方法是为这种类型创建我自己的接口,并在我的外观上有一个虚拟方法来访问它。然而,这对我来说似乎很混乱,因为我无法通过此方法强制访问该类型,而且很容易忘记。 例如,很自然地使用:
ConcreteType c = SomeInterface.ConcreteMember;
而不是:
IConcreteType c = GetConcreteMember(SomeInterface);
忘记这一点会导致测试失败。
我错过了一些基本的东西吗?正如我所说,我对单元测试非常陌生。
附注我正在使用起订量。
just started TDD and all was going well until I hit this brick wall.
I am writing a facade around a third party API. The API is quite nice in that everything is accessed via interfaces, so is easily mockable when testing my facade.
The whole API is accessed via a root interface and there is a deep hierarchy of interfaces you can drill down into from this. My facade takes this root interface in its constructor in standard IoC practice.
TDD was going fine, with the slight pain that mocking was getting a bit complex when using deep interfaces, since I have to mock the entire interface tree. No biggie though, I just maintained a helper function that built the mock. It does make me wonder if I'm using the right approach though.
Anyway, halfway down the tree I have now suddenly hit a sealed concrete type, with no public constructor, so I have no way of mocking it. This is causing my tests to fail since the mocked API always returns null for this member.
The only way I can see around this is to create my own interface for this type, and have a virtual method on my facade for accessing it. However, this seems messy to me since I have no way of enforcing access to the type through this method, and it will be easy to forget.
eg, it's natural to use:
ConcreteType c = SomeInterface.ConcreteMember;
instead of:
IConcreteType c = GetConcreteMember(SomeInterface);
Forgetting this would cause tests to fail.
Am I missing something fundamental? As I said I am very new to unit testing.
ps. I am using Moq.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用摩尔。通过使用它,您可以为任何密封类型创建模拟(我自己,我最近使用它来提供来自 System.Web.HttpContext.Current 属性的模拟)。
如果您查看下载中的文档(Microsoft Moles Reference Manual.docx),这应该为您提供足够的信息来帮助您入门。
Use moles. By using this, you can create mocks for any sealed type (myself, I recently used it to provide mocks from the System.Web.HttpContext.Current property).
If you look at the documentation in the download (Microsoft Moles Reference Manual.docx), this should give you enough information to get you started.