我希望能够在webforms页面对象上模拟ClientScriptManager类, 但似乎我不能,我得到的错误是我无法模拟密封的课程。
MockRepository mocks = new MockRepository()
Page page = mocks.PartialMock<Page>();
var clientScript = mocks.PartialMock<ClientScriptManager>(); //error here
SetupResult.For(page.ClientScript).Return(clientScript);
任何关于如何嘲笑客户管理员的建议都将不胜感激。
答案 0 :(得分:4)
正如您所发现的,您无法使用大多数模拟库来模拟密封类型。其中一个原因是许多模拟库通过创建派生类型来操作,但如果类是密封的,那么它们就无法从中派生出来。
我们在Microsoft内部所做的是我们使用手写IClientScriptManager
接口,然后使用实现该接口的ClientScriptManagerWrapper
并将所有调用委托给真实的ClientScriptManager
然后,无论需要使用ClientScriptManager
类型,它都会引用IClientScriptManager
。在运行时,我们创建一个ClientScriptManagerWrapper
(并传入真正的ClientScriptManager
)。在测试时,我们使用模拟对象库来创建模拟IClientScriptManager
并使用它来代替。
这是一个代码示例:
public class SomeClassThatNeedsClientScriptManager {
private IClientScriptManager _iClientScriptManager;
public IClientScriptManager IClientScriptManager {
get {
if (_iClientScriptManager == null) {
_iClientScriptManager = new ClientScriptManagerWrapper(Page.ClientScriptManager);
}
return _iClientScriptManager;
}
set {
_iClientScriptManager = value;
}
}
public void SomeMethodThatUsesClientScriptManager() {
IClientScriptManager.RegisterClientScriptBlock(typeof(Whatever), "key", "alert('hello')");
}
}
public interface IClientScriptManager {
void RegisterClientScriptBlock(Type type, string key, string script);
}
public class ClientScriptManagerWrapper : IClientScriptManager {
private readonly ClientScriptManager _clientScriptManager;
public ClientScriptManagerWrapper(ClientScriptManager clientScriptManager) {
if (clientScriptManager == null) {
throw new ArgumentNullException("clientScriptManager");
}
_clientScriptManager = clientScriptManager;
}
public void RegisterClientScriptBlock(Type type, string key, string script) {
_clientScriptManager.RegisterClientScriptBlock(type, key, script);
}
}
然后,您可以修改IClientScriptManager
界面和ClientScriptManagerWrapper
以获得所需的任何方法。