我需要僞造HttpContext.Current.Application
表才能從我的單元測試中訪問它。如何僞裝HttpContext進行單元測試?
我需要將我的數據存儲在某個地方。我認爲我可以通過NameValueCollectionBase
的實例,但是因爲我發現這個基類型沒有索引器,所以它看起來太複雜了。
那麼僞造HttpContext
這部分怎麼樣?可能嗎?我怎麼做到的?將NUnit.Mocks
有幫助嗎?
在此先感謝...
我需要僞造HttpContext.Current.Application
表才能從我的單元測試中訪問它。如何僞裝HttpContext進行單元測試?
我需要將我的數據存儲在某個地方。我認爲我可以通過NameValueCollectionBase
的實例,但是因爲我發現這個基類型沒有索引器,所以它看起來太複雜了。
那麼僞造HttpContext
這部分怎麼樣?可能嗎?我怎麼做到的?將NUnit.Mocks
有幫助嗎?
在此先感謝...
如果你需要的NameValueCollection基指數,請使用以下代碼
public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection collection)
{
if(collection == null)
{
throw new ArgumentNullException("collection");
}
return collection.Cast<string>().Select(key => new KeyValuePair<string, string>(key, collection[key]));
}
對於剛剛來存儲數據,並通過各地的測試方法,請使用上面的代碼。
在這種情況下,我生成了一些從System.Web.Abstractions中的基類派生的存根。我經常使用這種技術的MVC應用程序的MVC /的WebAPI控制器包含一個抽象的HttpContext(HttpContextBase)
這樣我可以存根出在我單位/集成測試HttpContext的要求,這裏是一個示例...
public class MockHttpApplicationState : HttpApplicationStateBase
{
private IDictionary<string, object> _appState = new Dictionary<string, object>();
public override void Add(string name, object value)
{
_appState.Add(name, value);
}
public override object Get(string name)
{
return _appState[name];
}
public override object this[string name]
{
get
{
return _appState[name];
}
set
{
_appState[name] = value;
}
}
}
public class MockHttpContext : HttpContextBase
{
private IDictionary<string, object> _appKeys;
public MockHttpContext()
{
}
/// <summary>
/// Accepts a dictionary of app keys to supply to the HttpApplicationState instance
/// </summary>
/// <param name="applicationState"></param>
public MockHttpContext(IDictionary<string,object> applicationState)
{
_appKeys = applicationState;
}
public override Cache Cache
{
get
{
return HttpRuntime.Cache;
}
}
public override HttpApplicationStateBase Application
{
get
{
var mockAppState = new MockHttpApplicationState();
foreach (string key in _appKeys.Keys)
{
mockAppState.Add(key, _appKeys[key]);
}
return mockAppState;
}
}
public override HttpRequestBase Request
{
get
{
return new HttpRequestWrapper(new HttpRequest(null,"http://localhost",null));
}
}
}
然後我的測試可以建立控制器和HTTP上下文:
private readonly OnlineShop.MVC.Controllers.HomeController _controller =
new MVC.Controllers.HomeController(null,new UnitOfWork());
[OneTimeSetUp]
public void Init()
{
var appKeys = new Dictionary<string, object>();
appKeys.Add("localhost", 1);
var httpContext = new MockHttpContext(appKeys);
_controller.ControllerContext = new ControllerContext()
{
Controller = _controller,
RequestContext = new RequestContext(httpContext, new RouteData())
};
}
[Test]
public void Index_Returns_HomeView()
{
var view = _controller.Index() as ViewResult;
var viewModel = view.Model as MVC.ViewModels.Home;
Assert.IsInstanceOf<OnlineShop.MVC.ViewModels.Home>(viewModel);
Assert.IsTrue(viewModel.FeaturedProducts.Count > 0);
}
我的控制器是意識到它的環境HttpContextBase實例提供緩存和應用程序狀態:
public ActionResult Index()
{
string cacheKey = string.Format("FeaturedProducts-{0}",WebsiteId);
IList<Product> productList = this.HttpContext.Cache[cacheKey] as IList<Product>;
//My app keeps a list of website contexts in the Application. This test returns 1 based on the unit/int tests or a real world db value when hosted on IIS etc..
int websiteId = (int)HttpContext.Application[this.Request.Url.Host];
問題是,如果是關於'User'的話,那麼很容易返回類型爲'IPrincipal'的新對象,但是當涉及到Application時,我需要返回一些沒有公共構造函數的HttpApplicationState對象並且因爲它是通過索引器使用的,所以很難用'NUnit.Mocks'僞造......你能提供一些這種情況的代碼示例嗎? – 2010-08-15 16:44:40
你好, 如果你需要的NameValueCollection基指數,請使用以下代碼 公共靜態的IEnumerable> ToPairs(這NameValueCollection中集) { 如果(集合== NULL){ 扔 新ArgumentNullException( 「集合」); } return collection.Cast ().Select(key => new KeyValuePair (key,collection [key])); } 僅用於存儲數據並傳遞測試方法,請使用上述代碼。 –
Venkat
2010-08-16 12:55:17
第一個鏈接不起作用 – 2012-02-01 15:01:45