如何模拟多个查询字符串?

时间:2014-04-30 05:21:20

标签: c# unit-testing mocking moq request.querystring

我想在我的单元测试类中模拟(通过moq)多个QueryStrings。 下面是一段代码: -

Adapter.MockQueryString("qs1", "1", _productController); 
Adapter.MockQueryString("qs2", "1", _productController); 

以下是我的Adapter类的静态函数: -

   public static void MockQueryString(string querystringKey, string querystringValue, Controller controller)
   {
       var queryString1 = new NameValueCollection();
       queryString1.Add(querystringKey, querystringValue);

       // Set up a request
       var request = new Mock<System.Web.HttpRequestBase>();
       request.Setup(r => r.QueryString).Returns(queryString1);

       // Inject into the controller
       var controllerBase = new Mock<ControllerBase>();
       var contextBase = new Mock<System.Web.HttpContextBase>();
       contextBase.Setup(c => c.Request).Returns(request.Object);

       request.Setup(r => r.QueryString).Returns(queryString1);
       var controllerContext = new ControllerContext(contextBase.Object, new System.Web.Routing.RouteData(), controllerBase.Object);
       controller.ControllerContext = controllerContext;
   }
  
    

问题是它只模拟最后一个查询字符串(qs2)。并为qs1提供null。我们可以模拟多个查询字符串吗?

  

2 个答案:

答案 0 :(得分:0)

Moq有SetupSequence,允许您在每次调用Mock后返回不同的结果

request.SetupSequence(r => r.QueryString)
       .Returns(queryString1)
       .Returns(queryString2);

您可能需要调整设置以接受收藏

修改

在一般情况下,您可能最好使用Setup使用有状态机制,例如通过闭包访问迭代器:

public static void MockQueryString(IEnumerable<Tuple<string, string>> qstringTuples, 
                                   Controller controller)
{
    // Convert collection to IEnum<NameValueCollection>
    var queryStrings = qstringTuples
        .Select(_ => new NameValueCollection {{_.Item1, _.Item2}})
        .ToList();
    // Set up a request
    var request = new Mock<System.Web.HttpRequestBase>();
    var queryStringIterator = queryStrings.GetEnumerator();
    request.SetupGet(r => r.QueryString)
           .Returns(() =>
                        {
                            queryStringIterator.MoveNext();
                            return queryStringIterator.Current;
                        });

答案 1 :(得分:0)

问题是您要设置属性以返回对象(NameValueCollectionqs1),然后将其设置为返回不同的对象(不同的{{ 1}}与NameValueCollection)。第二个qs2替换了第一个,这就是为什么你总是得到SetUp字符串。

qs2之外构建NameValueCollection并将其传入,因此您只需设置一次属性返回值:

MockQueryString

然后调用public static void MockQueryStrings(NameValueCollection queryStrings, Controller controller) { // Set up a request var request = new Mock<System.Web.HttpRequestBase>(); request.Setup(r => r.QueryString).Returns(queryStrings); ... etc } 一次:

MockQueryStrings