발견 한 것처럼 대부분의 조롱 라이브러리를 사용하여 봉인 된 유형을 조롱 할 수 없습니다. 이 이유 중 하나는 파생 된 유형을 작성하여 많은 모의 라이브러리가 작동하지만 클래스가 봉인 된 경우 파생 클래스에서 파생 될 수 없다는 것입니다.
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
는 당신이 필요로하는 어떤 방법을 가지고 :
그리고 여기에는 코드 샘플입니다.
내부적으로 너무 나쁘다. 더 많은 프레임 워크 유형이 공용 인터페이스와 래퍼를 구현하여 테스트 가능한 코드가 더 적은 레이어와 상호 운용 될 수 있도록하고 싶습니다. 하지만 이것이 우리가 래퍼를 포장하는 이유입니다. :) – maxwellb
@maxwellb 실제로 (ASP.NET 공간에서) 새로운 프레임 워크의 대부분을 보면 훨씬 많은 인터페이스와 추상 기본 클래스를 볼 수 있습니다. 예를 들어, MVC, Web API 및 SignalR은 모두 인터페이스를 많이 사용하므로 이러한 유형의 시나리오를 훨씬 쉽게 구현할 수 있습니다. – Eilon