C# 如何模拟多个查询字符串?
我想在单元测试类中模拟(通过moq)多个查询字符串。 下面是一段代码:-C# 如何模拟多个查询字符串?,c#,unit-testing,mocking,moq,request.querystring,C#,Unit Testing,Mocking,Moq,Request.querystring,我想在单元测试类中模拟(通过moq)多个查询字符串。 下面是一段代码:- Adapter.MockQueryString("qs1", "1", _productController); Adapter.MockQueryString("qs2", "1", _productController); 下面是适配器类的静态函数:- public static void MockQueryString(string querystringKey, string querystringVa
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;
}
publicstaticvoidmockquerystring(字符串querystringKey、字符串querystringValue、控制器)
{
var queryString1=新名称valuecollection();
添加(querystringKey,querystringValue);
//提出请求
var request=newmock();
request.Setup(r=>r.QueryString).Returns(queryString1);
//注入控制器
var controllerBase=new Mock();
var contextBase=new Mock();
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有,它允许您在每次调用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;
});
公共静态void MockQueryString(IEnumerable qstringTuples,
控制器(控制器)
{
//将集合转换为IEnum
var queryStrings=qstringTuples
.Select(=>newnamevalueCollection{{{{u0.Item1,0.Item2})
.ToList();
//提出请求
var request=newmock();
var queryStringIterator=queryStrings.GetEnumerator();
request.SetupGet(r=>r.QueryString)
.Returns(()=>
{
queryStringIterator.MoveNext();
返回queryStringIterator.Current;
});
问题在于,您正在设置一个属性以返回一个对象(使用qs1
的NameValueCollection
),然后将其设置为返回另一个对象(使用qs2
的另一个NameValueCollection
)
在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
}
@SturartLC,你能建议整个过程吗?我不是100%满足你的要求,但是上面的方法允许你预设N个值,从模拟返回到SUT。
SetupSequence
在一个简单的单元测试中,通过调用QueryString
,效果最好,但是因为你似乎已经抽象出了一个设置框架,y您可能希望在后续调用中按顺序返回每个值集合。请注意,“我的设置”->“查询字符串”中的早期错误是一个属性,而不是一个方法。
var queryStrings = new NameValueCollection();
queryStrings.Add("qs1", "1");
queryStrings.Add("qs2", "2");
Adapter.MockQueryStrings(queryStrings, _productController);