我在主题中得到了Exception:
System.ArgumentException :执行此操作需要HttpContext 操作。检查Web中是否正在执行此操作 请求。
每次我都试图测试一种方法。 我创建了一个HttpContext:
[TestInitialize]
public void Initialize()
{
#region declarations
Mock<IUnitOfWork> mock = new Mock<IUnitOfWork>();
Mock<IAntiForgeryValidator> antiForgeryMock = new Mock<IAntiForgeryValidator>();
var context = new Mock<HttpContextBase>();
#endregion
#region repository mock setups
mock.Setup(m => m.deviceRepository.Get(
It.IsAny<List<Expression<Func<Device, bool>>>>(),
It.IsAny<Func<IQueryable<Device>, IOrderedQueryable<Device>>>(),
null))
.Returns(new[] { new Device { Id = 1, Manufacturer = "a", Name = "b", CatalogNo = "x" } });
mock.Setup(m => m.deviceRepository.Get()).Returns(new[] { new Device { Id = 1, Manufacturer = "a", Name = "b", CatalogNo = "z" } });
mock.Setup(m => m.deviceRepository.GetByID(It.IsAny<int>())).Returns(new Device { Id = 1, Manufacturer = "a", Name = "b", CatalogNo = "15" });
mock.Setup(m => m.deviceRepository.GetByID(It.IsInRange(-1, 1, Range.Exclusive))).Returns(default(Device));
#endregion
#region Mocking Request in purpose of testing Post Methods
Mock<HttpRequestBase> Request = new Mock<HttpRequestBase>();
WebHeaderCollection Headers = new WebHeaderCollection();
Headers.Add("Connection", "keep-alive");
Headers.Add("Content-Length", "82");
Headers.Add("RequestVerificationToken", "AAAAAAAAAAAAAAAAAAAAAAA:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
Request.SetupGet(x => x.Headers).Returns(Headers);
context.SetupGet(x => x.Request).Returns(Request.Object);
#endregion
#region Mocking Validation
antiForgeryMock.Setup(m => m.Validate(
It.IsAny<string>(),
It.IsAny<string>()))
.Callback((string cookieToken, string formToken) =>
{
// call back
});
#endregion
DC = new DeviceController(fakeRepo);
DC.ControllerContext = new ControllerContext(context.Object,new RouteData(),DC);
}
但是在尝试执行以下代码时:
[TestMethod]
public void EditPost()
{
var data = default(Device);
var result = DC.Edit(data);
Assert.IsNotNull(result);
}
我不知道为什么我得到一个例外,告诉我没有HttpContext
。我创建它并将其绑定到控制器对象。
我正在测试代码:
[HttpPost]
//[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="Id,Name,Manufacturer,CatalogNo")] Device device)
{
ValidateRequestHeader(Request);
if (String.IsNullOrWhiteSpace(device.Name) || String.IsNullOrWhiteSpace(device.Manufacturer) || String.IsNullOrWhiteSpace(device.CatalogNo))
{
ModelState.AddModelError("", "Niepoprawne dane");
return PartialView(device);
}
unitOfWork.deviceRepository.Update(device);
unitOfWork.Save();
return Json(new { ok = true, newurl = Url.Action("Index") });
}
AntiForgeryValidator a = new AntiForgeryValidator();
public void ValidateRequestHeader(HttpRequestBase request)
{
string cookieToken = "";
string formToken = "";
if (request.Headers["RequestVerificationToken"] != null)
{
string[] tokens = request.Headers["RequestVerificationToken"].Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
a.Validate(cookieToken, formToken);
//AntiForgery.Validate(cookieToken, formToken);
}
public interface IAntiForgeryValidator
{
//void ValidateRequestHeader(HttpRequestBase request);
void Validate(string cookieToken, string formToken);
}
public class AntiForgeryValidator : IAntiForgeryValidator
{
public void Validate(string cookieToken, string formToken)
{
AntiForgery.Validate(cookieToken, formToken);
}
}
@Update
StackTrace指向此方法导致异常:AntiForgery.Validate(cookieToken, formToken);
答案 0 :(得分:1)
就像你在unitOfWork
中嘲笑Edit()
变量一样,设置IAntiForgeryValidator
。现在你明确地创建了一个真实的&#34; AntiForgeryValidator
在Edit()
之外使用该构造函数调用。只需将a
切换为与unitOfWork
相同的变量(假设您以某种方式注入unitOfWork
),并a
为IAntiForgeryValidator
,不是明确AntiForgeryValidator
,然后它应该工作。我假设您对unitOfWork
的模拟调用工作正常,我无法在您显示控制器中声明/实例化unitOfWork
变量的情况下提供更多详细信息。