开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜