我在测试 post 方法时遇到问题。 在该方法中,检查了 AntiForgeryToken,我不知道如何模拟它。 除此之外,一切正常。
这是我想测试的方法:
[HttpPost]
//[ValidateAntiForgeryToken]
public ActionResult Create([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.Insert(device);
unitOfWork.Save();
return Json(new { ok = true, newurl = Url.Action("Index") });
}
我已经 mock 过:
private IUnitOfWork fakeRepo;
DeviceController DC;
[TestInitialize]
public void Initialize()
{
Mock<IUnitOfWork> mock = new Mock<IUnitOfWork>();
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" } });
fakeRepo = mock.Object;
DC = new DeviceController(fakeRepo);
}
但我不知道如何测试 AntiforgeryToken
这里的代码:
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();
}
}
AntiForgery.Validate(cookieToken, formToken);
}
我无法注释掉这个调用测试目的,但这个解决方案看起来有点难看。
您能提出任何修改建议吗?
最佳答案
看来您需要模拟 HttpRequestBase
和AntiForgery
。
How do you mock them?
您将它们包装在自己的界面中,公开您需要或在不久的将来可能需要的行为。在您的生产代码中,您提供真正的 .NET 实现,在您的测试中,您的模拟。
MSDN 说 AntiForgery.Validate
Validates that input data from an HTML form field comes from the user who submitted the data.
signature that takes two string arguments返回void
.
你的模拟IAntiForgeryValidator
会有 Validate(string, string)
方法也返回 void。
public interface IAntiForgeryValidator
{
void Validate(string cookieToken, string formToken);
}
public class AntiForgeryValidator : IAntiForgeryValidator
{
public void Validate(string cookieToken, string formToken)
{
AntiForgery.Validate(cookieToken, formToken);
}
}
您可以对 void 方法使用回调并验证它们被调用的次数是否正确:
antiForgeryMock.Setup(m => m.Validate(
It.IsAny<string>(),
It.IsAny<string>()))
.Callback((string cookieToken, string formToken) =>
{
// call back
});
antiForgeryMock.Verify(m => m.Validate(
It.IsAny<string>(),
It.IsAny<string>()), Times.Once());
您还有另一个选择(作弊),那就是将您的调用 stub 到 ValidateRequestHeader()
在Create()
。这将使您能够测试其余代码,但不推荐,因为真正的 ValidateRequestHeader()
如果您不测试该方法,可能会在您的生产代码中造成问题。
关于c# - 如何对 POST 方法进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22399570/