我们正在考虑用MVC3做一些单元测试。我认为一个合理的解决方案是标记返回"B“视图的操作,并标记其他操作,以便记录结果。
也许控制器看起来像这样:
[AB(ABModes.View)]
public ActionResult SignUp()
{
return View();
}
[HttpPost]
public ActionResult SignUp(int id)
{
return RedirectToAction("Confirmation");
return View();
}
[AB(ABModes.Result)]
public ActionResult Confirmation()
{
return View();
}SignUp将返回A或B视图,并且确认将记录使用了哪个视图。
该属性将如下所示:
using System;
using System.Web.Mvc;
namespace ABTesting.lib
{
public class ABAttribute : ActionFilterAttribute
{
private ABModes mode;
private Abstract.IABChooser abChooser;
private Abstract.IABLogMessenger abMessenger;
public ABAttribute(ABModes mode) : this(mode, new Concrete.ABChooser(), null)
{
}
public ABAttribute(ABModes mode, Abstract.IABChooser abChooser, Abstract.IABLogMessenger abMessenger)
{
this.mode = mode;
this.abChooser = abChooser;
this.abMessenger = abMessenger;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var result = filterContext.Result as ViewResultBase;
var action = filterContext.Controller.ControllerContext.RouteData.Values["action"].ToString();
var actionName = String.IsNullOrEmpty(result.ViewName) ? action : result.ViewName;
if(mode == ABModes.View)
result.ViewName = String.Format("{0}{1}", actionName, abChooser.UseB()? "_B" : String.Empty);
else{
var controller = filterContext.Controller.ControllerContext.RouteData.Values["controller"].ToString();
if (abMessenger != null)
abMessenger.Write(new Entities.ABLogMessage
{
DateCreated = DateTime.Now,
ControllerName = controller,
ActionName = actionName,
IsB = abChooser.UseB()
});
}
base.OnActionExecuted(filterContext);
}
}
}和
public interface IABChooser
{
bool UseB();
}和
public interface IABLogMessenger
{
void Write(ABLogMessage message);
}这看起来像是一种合理的方式,只需最少的代码更改就能实现这一点吗?
发布于 2014-04-14 09:05:20
这看起来确实是一个合理的解决方案。我之所以知道这一点,是因为我使用了同样的概念来开发A/B测试框架(http://www.nuget.org/packages/AbTestMaster)。它可以在nuget上免费获得,也是开源的。
这可能会让你的生活稍微简单一点。
https://stackoverflow.com/questions/18317734
复制相似问题