Create a mock of ClientScriptManager with Rhino Mocks
I would like to be able to mock the ClientScriptManager class on a webforms Page object, however it seems like I can't, I get the error that I can't mock a sealed class.
MockRepository mocks = new开发者_开发技巧 MockRepository()
Page page = mocks.PartialMock<Page>();
var clientScript = mocks.PartialMock<ClientScriptManager>(); //error here
SetupResult.For(page.ClientScript).Return(clientScript);
Any advice on how to mock the clientscriptmanager would be appreciated.
As you've discovered, you can't use most mocking libraries to mock sealed types. One reason for this is that many mock libraries operate by creating a derived type but if the class is sealed then they can't derive from it.
What we've done internally at Microsoft is that we use a hand-written IClientScriptManager
interface and then use a ClientScriptManagerWrapper
that implements that interface and delegates all calls to a real ClientScriptManager
.
Then whatever type needs to use the ClientScriptManager
it will instead have a reference to an IClientScriptManager
. At runtime we create a ClientScriptManagerWrapper
(and pass in the real ClientScriptManager
). At test time we use a mock object library to create a mock IClientScriptManager
and use that instead.
And here's a code sample:
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);
}
}
You can then modify the IClientScriptManager
interface and the ClientScriptManagerWrapper
to have whatever methods you need.
精彩评论