TDD和保护方法

本文关键字:方法 保护 TDD | 更新日期: 2023-09-27 17:50:57

我试图通过创建现有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;
    }
}

TDD和保护方法

仅仅进行测试并不能使其成为TDD。如果您已经假设私有方法做了一些事情,那么开发不是由测试驱动的,对吗?

尝试先盲写测试,您可能最终根本不需要私有方法,甚至将其作为另一个类中的公共方法。

是的,您的测试用例是正确的,您只能测试您可以调用的方法。通常公共方法是可测试的。同样,如果您的组件中有一个私有方法,这意味着它必须被该组件中的至少一个公共方法调用。当你在测试你的公共方法时,你也在同一个测试中测试了私有方法的功能。您可以考虑将私有方法作为公共方法之外的几行公共方法,以使代码更具可读性和可重用性。

Protected方法在你正在创建的类和它未来的子类之间创建了一个契约。如果你不想创建这个契约,你可以将方法定义为private,而不是protected。因此,我认为您应该测试这些方法的行为是否符合任何派生类的期望。

考虑两个类:

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

如果您乐于在ConcreteMathClass的测试中测试Mult方法的功能,那么您就不需要为基类编写测试。但是,如果您确实为基类编写了测试,那么在编写基类时就巩固了契约,这意味着任何派生类都知道它们所签署的是什么。你站在哪一边,取决于你自己的看法。这个问题有其他的看法。

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

实现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,因为目前在你的公共接口上还不需要它。

你可能也对这个问题的答案感兴趣。