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.