如何设置一个查询字符串的值在测试方法Moq的 [英] How to set the value of a query string in test method Moq

查看:224
本文介绍了如何设置一个查询字符串的值在测试方法Moq的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下控制器的操作方法,我编写单元测试这种方法

I have the following controller action method and I am writing a unit test for this method

    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 
    }

和这里是我已经为它编写单元测试之一,

And Here is one of the unit Test which I have written for it,

    [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");
    }

当我试图运行测试其投掷的错误:未设置对象引用到对象的实例,而该行的数字显示为的Request.QueryString,如何设置会话变量的测试方法,任何人都可以建议我什么是检查控制器操作的返回类型的正确方法。

When I am trying to run the test its throwing error: Object reference not set to an instance of object , and the line number shows to request.querystring , How to set the session variables in test methods, and Can anyone suggest me what is the proper way to check a controller action return type.

推荐答案

查询字符串

您还将需要模拟在 HttpRequestBase 对象的查询字符串。对于您将需要建立对象图

You will also need to mock the query string in the HttpRequestBase object. For that you will need to build the object graph

ControllerContext - > HttpContextBase - > HttpRequestBase

ControllerContext -> HttpContextBase -> HttpRequestBase

因为你已经嘲讽 ControllerContext <控制器实例/ code>,可以使用下面的代码添加嘲笑查询字符串:

As you are already mocking the ControllerContext of your controller instance, you can use the following code to add the mocked query string:

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);



会议

有关嘲笑的会话,使用上面配置了相同的HTTP上下文也返回一个模拟会话对象:

For the mocked session, use the same http context configured above to also return a mock session object:

var mockSession = new Mock<HttpSessionStateBase>();
mockHttpContext.Setup(c => c.Session).Returns(mockSession.Object);
//where mockHttpContext has been created in the code for the queryString above and setup to be returned by the controller context


$返回b $ b

然后就可以设置的值你是使用 SetupGet 的样子,或者你也可以使用设置

Then you can set the values the way you did using SetupGet, or you can also use Setup as in

mockSession.Setup(s => s["token"]).Returns("fooToken")

如果您想验证一个价值上的会话设置,您可以添加这样的事情你断言代码:

If you want to verify that a value was set on the session, you can add something like this to your assert code:

mockSession.VerifySet(s => s["token"] = "tokenValue", Times.Once);



的ActionResult类型

我最常做的就是使用operator 。如果转换是不可能的,将返回null。因此,断言可能看起来是这样的:

What I usually do is to cast the result to the desired type using the as operator. It will return null if the conversion is not possible. So the assert may look like this:

ViewResult result = controller.Index() as ViewResult;

// Assert
Assert.IsNotNull(result);
Assert.AreEqual("fooView", result.ViewName);






侧注意

如果您拥有的代码使用会话和/或查询字符串很多类似的测试,会有相当,你需要创建和配置在每个测试的几个mock对象

If you have many similar tests where the code is using the session and/or query string, there will be quite a few mock objects you need to create and configure on every test.

您可以添加一个设置方法来测试类(这是每个测试之前运行),并搬到那里所有的构建与嘲笑的对象图的代码。这样,您对每个测试方法一个新的控制器实例和安排每个测试的一部分,将只需要设置嘲笑的行为和期望值。

You could add a setup method to your test class (which is run before each test), and move there all the code that builds the object graph with the mocks. This way you have a fresh controller instance on every test method and the arrange part of every test will just need to setup the mocks behaviour and expectations.

例如,如果您有这样的设置代码在测试类:

For example, if you have this setup code in your test class:

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;
}

在每个测试的代码将减少到这样的事情:

The code on every test will be reduced to something like this:

[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);
}



如果这些测试是测试这种哑指标法

Where those tests are testing this dummy Index method

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

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

这篇关于如何设置一个查询字符串的值在测试方法Moq的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆