如何模拟多个查询字符串



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

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

下面是我的适配器类的静态函数:-

   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。我们如何模拟多个查询字符串?

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

问题是,您要设置一个属性以返回一个对象(NameValueCollectionqs1(,然后设置它以返回不同的对象(不同的NameValueCollectionqs2(。第二个SetUp替换第一个,这就是为什么您总是得到qs2字符串。

MockQueryString之外构建NameValueCollection并传入,因此只设置一次属性返回值:

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一次:

var queryStrings = new NameValueCollection();
queryStrings.Add("qs1", "1");
queryStrings.Add("qs2", "2");
Adapter.MockQueryStrings(queryStrings, _productController); 

相关内容

  • 没有找到相关文章

最新更新