TDD和受保护的方法

时间:2015-05-27 06:11:57

标签: c# asp.net-mvc tdd

我正在尝试通过创建现有MVC应用程序的副本来学习TDD,但我正在使用TDD从头开始创建它的副本。

在我现有的应用程序中,我有一个Application_AuthenticateRequest方法,如下所示。

这是受保护的。我是否正确地认为不应该测试这些方法 - 即您应该只测试公共方法而不是私有方法和受保护方法。如果这是真的,那么我只是编写我的受保护方法而不编写任何测试吗?

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        StaticDataSeeder.Seed();
    }

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie == null) return;

        var authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        if (authTicket == null) return;

        var userData = new UserDataModel(authTicket.UserData);

        var userPrincipal = new PaxiumPrincipal(new GenericIdentity(authTicket.Name), null)
        {
            Email = userData.Email,
            Menu = userData.Menu,
            RememberMe = userData.RememberMe
        };

        Context.User = userPrincipal;
    }
}

3 个答案:

答案 0 :(得分:3)

只是进行测试并不能使其成为TDD。如果你已经假定私有方法做某事,那么开发并没有被测试所驱动,是吗?

首先尝试失明并编写测试,最终可能不需要私有方法,甚至不能将其作为另一个类中的公共方法。

答案 1 :(得分:1)

是的,您的测试用例是正确的,您只能测试可以调用的方法。所以一般公共方法都是可测试的。同样,如果组件中有私有方法,则意味着必须由该组件中的至少一个公共方法调用它。因此,当您测试公共方法时,您也在同一测试中测试私有方法的功能。私有方法,你可以考虑公共方法的几行,保留公共方法,使代码更具可读性和可重用性。

答案 2 :(得分:0)

受保护的方法会在您创建的课程及其未来的孩子之间创建合同。如果您不想创建此合同,则可以将方法定义为私有,而不是受保护。因此,我认为您应该测试这些方法的行为是否符合任何派生类所期望的期望。

考虑两个类:

public abstract class BaseMathsClass {
    protected int Mult(int a, int b) {
        return a * b;
    }
}

public class ConcreteMathClass : BaseMathsClass {
    public int Square(int x) {
        return Mult(x, x);
    }
}

如果您对Mult的测试中的ConcreteMathClass方法的功能感到满意,那么您就不需要为基类编写测试。但是,如果您为基类编写测试,则会在编写基类时粘合合同,这意味着任何派生类都知道他们注册的内容。你所依据的围栏的哪一侧,取决于你的意见。 This question还有其他一些意见。

你还说你相信你不需要测试私人方法。这是正确的,因为您不需要编写特定的测试来直接调用私有方法,但是您应该通过针对类的公共方法的测试隐式地测试任何私有方法的功能。在编写测试时,如果您的课程具有以下任一实现,您就不应该非常关心:

实施1

class MyClass {
    public int GetSquare(int someValue) {
        return someValue * someValue;
    }
}

实施2

class MyClass {
    public int GetSquare(int someValue) {
        return Mult(someValue, someValue);
    }

    private int Mult(int a, int b) {
        return a * b;
    }
}

使用实施2 ,您不需要编写专门调用Mult的测试,GetSquare的测试可以充分运用此代码。这并不意味着您只需编写另一个私有方法Add,因为目前公共接口上不需要它。

您可能也对this question的答案感兴趣。