Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# 如何在测试方法Moq中设置查询字符串的值_C#_Unit Testing_Nunit_Moq - Fatal编程技术网

C# 如何在测试方法Moq中设置查询字符串的值

C# 如何在测试方法Moq中设置查询字符串的值,c#,unit-testing,nunit,moq,C#,Unit Testing,Nunit,Moq,我有下面的控制器操作方法,我正在为此方法编写一个单元测试 try { if ( Session["token"] == null) { //checking whether the user has already given the credentials and got redirected by survey monkey by checking the query string 'code' if

我有下面的控制器操作方法,我正在为此方法编写一个单元测试

    try
    {
    if ( Session["token"] == null)
        {
            //checking whether the user has already given the credentials and got redirected by survey monkey by  checking the query string 'code'
            if (Request.QueryString["code"] != null)
            {
                string tempAuthCode = Request.QueryString["code"];
                Session["token"] = _surveyMonkeyService.GetSurveyMonkeyToken(ApiKey, ClientSecret, tempAuthCode, RedirectUri, ClientId);
            }
            else
            {
                //User coming for the first time directed to authentication page
                string redirectUrlToSurveyMonkeyAuthentication = _surveyMonkeyService.GetUrlToSurveyMonkeyAuthentication(RedirectUri, ClientId, ApiKey);
                return Redirect(redirectUrlToSurveyMonkeyAuthentication);
            }
        }    
        //User is in the same session no need for token again showing surveys without authentication
        var model = _surveyService.GetSurveys(User.Identity.Name);
        if (model.Count == 0)
            return View(CSTView.NoSurveyTracker.ToString());
        return View(CSTView.Index.ToString(), model);
    }
    catch (Exception e)
    {
        return DisplayErrorView(e);//Even this returns a redirect method 
    }
这是我为它编写的一个单元测试

    [Test]
    public void GetIndexPage_Returns_View_With_ValidToken()
    {
        var mockControllerContext = new Mock<ControllerContext>();
        var mockSession = new Mock<HttpSessionStateBase>();
        mockSession.SetupGet(s => s["SurveyMonkeyAccessToken"]).Returns(SampleToken);
        mockSession.SetupGet(c => c["code"]).Returns(SampleTempAuthCode);
        mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object);
        _surveyTrackerController.ControllerContext = mockControllerContext.Object;
        _surveyServiceMock.Setup(x => x.GetSurveys(TestData.TestData.SampleUserName)).Returns(SurveyTrackerList);
        var result = _surveyTrackerController.GetIndexPage();
        Assert.IsInstanceOf(typeof(ActionResult), result);
        Assert.AreEqual(((ViewResult)result).ViewName, "expected");
    }
[测试]
public void GetIndexPage\返回带有\u ValidToken()的\u视图\u
{
var mockControllerContext=new Mock();
var mockSession=new Mock();
SetupGet(s=>s[“SurveyMonkeyAccessToken”])。返回(SampleToken);
SetupGet(c=>c[“code”])。返回(SampleTempAuthCode);
mockControllerContext.Setup(p=>p.HttpContext.Session).Returns(mockSession.Object);
_surveyTrackerController.ControllerContext=mockControllerContext.Object;
_surveyServiceMock.Setup(x=>x.GetSurveys(TestData.TestData.SampleUserName)).Returns(SurveyTrackerList);
var result=_surveyTrackerController.GetIndexPage();
Assert.IsInstanceOf(typeof(ActionResult),result);
Assert.AreEqual(((ViewResult)result.ViewName,“预期”);
}

当我试图运行测试时,它的抛出错误是:Object reference未设置为Object的实例,行号显示为request.querystring,如何在测试方法中设置会话变量,有人能告诉我检查控制器操作返回类型的正确方法吗

查询字符串

您还需要模拟
HttpRequestBase
对象中的查询字符串。为此,您需要构建对象图

ControllerContext
->
HttpContextBase
->
HttpRequestBase

由于您已经在模拟控制器实例的
ControllerContext
,因此可以使用以下代码添加模拟的查询字符串:

var queryString = new NameValueCollection { { "code", "codeValue" } };
var mockRequest = new Mock<HttpRequestBase>();
mockRequest.Setup(r => r.QueryString).Returns(queryString);
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.Request).Returns(mockRequest.Object);
mockControllerContext.Setup(c => c.HttpContext).Returns(mockHttpContext.Object);
如果要验证会话上是否设置了值,可以向断言代码中添加如下内容:

mockSession.VerifySet(s => s["token"] = "tokenValue", Times.Once);
操作结果类型

我通常做的是使用
as
将结果强制转换为所需的类型。如果无法进行转换,它将返回null。因此断言可能如下所示:

ViewResult result = controller.Index() as ViewResult;

// Assert
Assert.IsNotNull(result);
Assert.AreEqual("fooView", result.ViewName);
[Test]
public void Index_WhenNoTokenInSession_ReturnsDummyViewAndSetsToken()
{
    // Arrange
    var queryString = new NameValueCollection { { "code", "dummyCodeValue" } };
    _mockSession.Setup(s => s["token"]).Returns(null);
    _mockRequest.Setup(r => r.QueryString).Returns(queryString);

    // Act
    ViewResult result = _homeController.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual("dummy", result.ViewName);
    _mockSession.VerifySet(s => s["token"] = "tokenValue", Times.Once);
}

[Test]
public void Index_WhenTokenInSession_ReturnsDefaultView()
{
    // Arrange
    _mockSession.Setup(s => s["token"]).Returns("foo");

    // Act
    ViewResult result = _homeController.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual(String.Empty, result.ViewName);
}

旁注

如果您有许多类似的测试,其中代码使用会话和/或查询字符串,那么您需要在每个测试中创建和配置相当多的模拟对象

您可以向您的测试类添加一个setup方法(在每次测试之前运行),并将使用mock构建对象图的所有代码移到该类中。这样,每个测试方法上都有一个新的控制器实例,每个测试的安排部分只需要设置模拟行为和期望

例如,如果测试类中有此设置代码:

private HomeController _homeController;
private Mock<HttpSessionStateBase> _mockSession;
private Mock<HttpRequestBase> _mockRequest;

[SetUp]
public void Setup()
{
    _mockRequest = new Mock<HttpRequestBase>();
    _mockSession = new Mock<HttpSessionStateBase>();
    var mockHttpContext = new Mock<HttpContextBase>();
    var mockControllerContext = new Mock<ControllerContext>();

    mockHttpContext.Setup(c => c.Request).Returns(_mockRequest.Object);
    mockHttpContext.Setup(c => c.Session).Returns(_mockSession.Object);
    mockControllerContext.Setup(c => c.HttpContext).Returns(mockHttpContext.Object);

    _homeController = new HomeController();
    _homeController.ControllerContext = mockControllerContext.Object;
}
其中,这些测试正在测试此虚拟索引方法

public ActionResult Index()
{
    if (Session["token"] == null)
    {
        if (Request.QueryString["code"] != null)
        {

            Session["token"] = "tokenValue";
            return View("dummy");
        }
    }
    return View();
}

谢谢。。您能否建议我如何测试返回重定向(URL)方法。将控制器结果强制转换为
RedirectResult
并检查其URL属性
[Test]
public void Index_WhenNoTokenInSession_ReturnsDummyViewAndSetsToken()
{
    // Arrange
    var queryString = new NameValueCollection { { "code", "dummyCodeValue" } };
    _mockSession.Setup(s => s["token"]).Returns(null);
    _mockRequest.Setup(r => r.QueryString).Returns(queryString);

    // Act
    ViewResult result = _homeController.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual("dummy", result.ViewName);
    _mockSession.VerifySet(s => s["token"] = "tokenValue", Times.Once);
}

[Test]
public void Index_WhenTokenInSession_ReturnsDefaultView()
{
    // Arrange
    _mockSession.Setup(s => s["token"]).Returns("foo");

    // Act
    ViewResult result = _homeController.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual(String.Empty, result.ViewName);
}
public ActionResult Index()
{
    if (Session["token"] == null)
    {
        if (Request.QueryString["code"] != null)
        {

            Session["token"] = "tokenValue";
            return View("dummy");
        }
    }
    return View();
}