NUnit 模拟不适用于单例方法
请耐心等待,我是 NUnit 的新手。我来自 Rails 的土地,所以其中一些对我来说是新的。
我有一行代码,如下所示:
var code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
我正在尝试模拟它,如下所示(假设 code
已初始化):
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
当我调试测试时,getCodeByCodeNameAndType
返回 null
,而不是预期的 code
。我做错了什么?
NUnit版本:2.2.8
Bear with me, I'm new to NUnit. I come from the land of Rails, so some of this is new to me.
I have a line of code that looks like this:
var code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
I'm trying to mock it, like this (assume code
is already initialized):
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
When I debug the test, getCodeByCodeNameAndType
is returning null
, instead of the expected code
. What am I doing wrong?
NUnit version: 2.2.8
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
抱歉,我从未使用过 NUnit.Mocks - 但我确实有一些使用 NMock 和 Moq 的经验 [顺便说一句,我强烈推荐]。通常,您使用模拟库来生成接口定义的代理,并且我认为 NUnit.Mocks 的操作方式相同。
因此,如果您想嘲笑您的单身人士,您可能必须执行以下操作
:创建一个接口,例如
b。 “实施”接口
C.消费接口
好了,所以步骤c。这是您大部分工作的地方。从逻辑上讲,如果您正在嘲笑您的单例,那么您实际上是在对消费者进行单元测试(您已将其排除在样本之外)。对于c。只需向使用者的构造函数添加一个参数,或者添加一个“IWebSiteConfiguration”类型的可公开访问的属性,然后在内部引用实例成员并针对这个新接口调用您的方法。考虑一下,
就
变成了
在你的单元测试中,创建模拟,将模拟的引用传递给消费者,然后测试消费者。
这也可以作为依赖注入 [DI] 的实用介绍。这只是将服务引用(例如您的网站配置类)传递或“注入”给消费者的做法,而不是让消费者直接调用服务(例如通过静态单例类)。
希望这有帮助:)
I'm sorry, but I've never used NUnit.Mocks - but I do have some experience with NMock and Moq [which, by the way, I highly recommend]. Typically, you use a mocking library to generate proxies for Interface definitions, and I presume NUnit.Mocks operates the same way.
Therefore, if you would like to mock your singleton, you will likely have to do the following,
a. Create an interface, say
b. "Implement" interface
c. Consume interface
alright, so step c. is where most of your work will be. Logically, if you are mocking your singleton, you are actually unit testing the consumer [which you have left out of your sample]. For c. simply add a parameter to the consumer's ctor, or add a publicly accessible property of Type 'IWebSiteConfiguration', and then internally, reference the instance member and invoke your methods against this new interface. Consider this,
was
becomes
In your unit test, create the mock, pass a reference of the mock to the consumer, and test the consumer.
This also serves as a practical introduction to Dependency Injection [DI]. It's simply the practice of passing, or "injecting", references of services [eg your web site configuration class] to the consumer, rather than having the consumer invoke the service directly [eg via static singleton class].
Hope this helps :)
DynamicMock 在内存中创建一个新对象,该对象表示要模拟的接口或可编组(继承自 MarshalByRef)类。
试试这个:
请注意,除非 WebSiteConfiguration 继承自 MarshalByRef,否则第三行将不起作用。
您通常做的是模拟一个接口并获取一个实现该接口的新对象,但其行为方式与您配置它的方式相同,而不必为其创建具体类型,所以我不完全确定什么除非您采用更好的隔离框架,例如可以拦截对现有对象中静态方法/属性的调用的 TypeMock,否则您所做的将会起作用。
A DynamicMock creates a new object in-memory that represents the interface, or marshallable (inherits from MarshalByRef) class you want to mock.
Try this:
Note that the third line there will not work unless WebSiteConfiguration inherits from MarshalByRef.
What you typically do is mock an interface and get a new object that implements this interface, but behaves the way you've configured it to do, without having to go and make a concrete type for it, so I'm not entirely sure what you're doing is going to work unless you employ a better isolation framework, like TypeMock that can intercept calls to static methods/properties in existing objects.
似乎有一种使用反射的解决方案,或者也许我完全误解了这一点。
这里讨论的是:
http://www.geekbeing .com/2010/05/23/how-to-unit-test-singleton-hack-in-c
它真的有效吗?
项目在 https://github.com/rbabreu/TestableSingleton 上可用
实际上我无法在 Visual Studio 上编译它因为 SingletonClass 有一个私有构造函数。如果有人让它工作,那么就可以避免适配器模式的开销。
Seems there is a kind of solution for this using reflection, or maybe I totally misunderstood this.
It is discussed here:
http://www.geekbeing.com/2010/05/23/how-to-unit-test-singleton-hack-in-c
Could it really works?
Project availabe on https://github.com/rbabreu/TestableSingleton
Actually I could not compile it on Visual Studio since the SingletonClass would have a private constructor. If someone get it to work would be great to avoid the overhead of adapter pattern.