首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ActionFilterAttribute执行ABTesting

使用ActionFilterAttribute执行ABTesting
EN

Stack Overflow用户
提问于 2013-08-19 23:38:37
回答 1查看 79关注 0票数 0

我们正在考虑用MVC3做一些单元测试。我认为一个合理的解决方案是标记返回"B“视图的操作,并标记其他操作,以便记录结果。

也许控制器看起来像这样:

代码语言:javascript
复制
[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视图,并且确认将记录使用了哪个视图。

该属性将如下所示:

代码语言:javascript
复制
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);
        }
    }
}

代码语言:javascript
复制
public interface IABChooser
{
    bool UseB();
}

代码语言:javascript
复制
public interface IABLogMessenger
{
    void Write(ABLogMessage message);
}

这看起来像是一种合理的方式,只需最少的代码更改就能实现这一点吗?

EN

回答 1

Stack Overflow用户

发布于 2014-04-14 09:05:20

这看起来确实是一个合理的解决方案。我之所以知道这一点,是因为我使用了同样的概念来开发A/B测试框架(http://www.nuget.org/packages/AbTestMaster)。它可以在nuget上免费获得,也是开源的。

这可能会让你的生活稍微简单一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18317734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档