我想测试依赖于硬件C#类的控制器,而不是接口。
它被配置为单身,我无法弄清楚如何使用RhinoMock。
依赖类的硬件元数据(示例):
namespace Hardware.Client.Api
{
public class CHardwareManager
{
public static CHardwareManager GetInstance();
public string Connect(string clientId);
}
}
在我的代码中我希望这样的东西返回true,否则我得到一个异常
if( !CHardwareManager.GetInstance().Connect("foo") )
我用它来嘲笑:
CHardwareManager mockHardwareMgr MockRepository.GenerateMock<CHardwareManager>();
但Connect需要一个GetInstance,我可以“编译”的唯一组合是
mockHardwareMgr.Expect (x => x.Connected ).Return(true).Repeat.Any();
但它没有正确模拟,它会引发异常
但是抱怨输入GetInstance
mockHardwareMgr.Expect (x => x.GetInstance().Connected).Return(true).Repeat.Any();
所以我的问题 - 我认为 - 正在嘲笑一个单身人士。然后我不知道如何让我的控制器使用这个模拟,因为我没有将模拟传递给控制器。它是一个资源和命名空间。
我的工作中有90%需要我需要模拟的外部组件,大部分时间我都没有编写类或接口,而且我很难对它们进行模拟和测试代码。
欢迎任何指示。
提前致谢(是的,我一直在搜索SO并且没有看到类似的东西。但是,也许我的搜索效果不佳。
答案 0 :(得分:1)
避免模拟外部组件问题的常用方法是不要直接在代码中使用它们。相反,定义anti-corruption layer(通常通过看起来像外部组件的接口)并使用此接口的模拟实现来测试代码。毕竟,您正在测试自己的代码,而不是外部代码。
更好的方法是根据您的需要调整此界面,这样它只会暴露您实际需要的东西,而不是外部组件提供的整个API(因此它实际上是适配器模式)。
使用不同的方法测试外部组件:系统测试,在这种情况下,您实际上没有模仿它们,您使用实际的实现。
通常当你试图让Rhino Mocks做一些感觉不自然和犀牛咆哮的事情时,这是一个很好的信号,表明你的方法不正确。几乎所有事情都可以使用简单的界面模拟来完成。
答案 1 :(得分:0)
正如Igor所说,RhinoMocks(以及大多数其他免费模拟框架,例如Moq)只能模拟接口。
对于模拟类,尝试(和支付)TypeMock。
对于嘲笑单身人士,请参阅我的回答: How to Mock a Static Singleton?
是的,我有点破坏了对什么是可测试的,因此“好”代码的共同理解。然而,我开始怨恨这样的答案,比如“你做错了。重新做一切。”对于那些答案并没有解决手头的问题。
不,这并不是指着伊戈尔,而是在许多其他类似线程中,谁回答说“单身人士不可撼动。(重新做一切。)”。