使用Rhino Mocks创建ClientScriptManager的模拟

时间:2010-01-03 01:31:35

标签: c# asp.net rhino-mocks

我希望能够在webforms页面对象上模拟ClientScriptManager类, 但似乎我不能,我得到的错误是我无法模拟密封的课程。

MockRepository mocks = new MockRepository()

Page page = mocks.PartialMock<Page>();

var clientScript = mocks.PartialMock<ClientScriptManager>(); //error here

SetupResult.For(page.ClientScript).Return(clientScript);

任何关于如何嘲笑客户管理员的建议都将不胜感激。

1 个答案:

答案 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以获得所需的任何方法。