Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用单元测试POST方法_C#_Unit Testing - Fatal编程技术网

C# 如何使用单元测试POST方法

C# 如何使用单元测试POST方法,c#,unit-testing,C#,Unit Testing,我对测试post方法有问题。 在这种方法中,AntiForgeryToken被检查,我不知道如何模拟它。 除此之外,一切正常 下面是我要测试的方法: [HttpPost] //[ValidateAntiForgeryToken] public ActionResult Create([Bind(Include="Id,Name,Manufacturer,CatalogNo")] Device device) { ValidateRequestHeader(

我对测试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") });
    }
我已经嘲笑过:

        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);
    }
我无法评论这个呼叫测试的目的,但这个解决方案似乎有点难看


您能提出任何编辑建议吗?

看起来您需要模拟
HttpRequestBase
AntiForgery

你怎么嘲笑他们

您可以将它们封装在自己的接口中,公开您需要或可能在不久的将来需要的行为。在生产代码中,您提供了真实的.NET实现,在测试中,您提供了模拟

MSDN显示反伪造。验证

验证来自HTML表单字段的输入数据是否来自用户 谁提交了数据

返回
void

您的mock
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());
antiForgeryMock.Setup(m=>m.Validate(
It.IsAny(),
It.IsAny())
.Callback((字符串cookieToken,字符串formToken)=>
{
//回电
});
antiForgeryMock.Verify(m=>m.Validate(
It.IsAny(),
It.IsAny()),Times.Once();

您还有另一个选择(作弊),那就是在
Create()
中存根调用
ValidateRequestHeader()
。这将使您能够测试其余代码,但不会被重新引用,因为如果您不测试该方法,则实际的
验证请求阅读器()
可能会在生产代码中造成问题。

谢谢。您的代码将允许我模拟
AntiForgery.Validate(cookieToken,formToken)但测试将已经失败,因为此行抛出异常:
if(request.Headers[“RequestVerificationToken”!=null)
这就是为什么您还需要模拟
HttpRequestBase
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());