简体   繁体   中英

ASP.net MVC RTM Test naming conventions

I am working on an asp.net mvc application and writing my unit tests BDD style. Eg.

GetResource_WhenResourceFileExists_ShouldReturnResources()

But when I am writing tests for my controllers, I usually have two Methods with the same name. One without parameters for get requests and one with for posts. Does anybody have a good naming convention here to distinguish between the two?

I can think of:

1.
LogIn_WithParameters_ShouldReturnLogInView()
LogIn_WithoutParameters_WhenAuthenticationFailed_ShouldReturnLogInView()
LogIn_WithoutParameters_WhenAuthenticationPassed_ShouldReturnProfileRedirect()

2.
LogIn_Get_ShouldReturnLogInView()
LogIn_Post_WhenAuthenticationFailed_ShouldReturnLogInView()
LogIn_Post_WhenAuthenticationPassed_ShouldReturnProfileRedirect()

3.
LogIn_ShouldReturnLogInView()
LogIn_WhenCalledWithParametersAndAuthenticationFailed_ShouldReturnLogInView()
LogIn_WhenCalledWithParametersAndAuthenticationPassed_ShouldReturnProfileRedirect()

Any opinions?

I use the following format which works very well for me:

[TestFixture]    
public class Log_in_with_parameters_should
{
    [Test]
    public void Return_the_log_in_view() {}
}

[TestFixture]    
public class Log_in_without_parameters_should
{
    [Test]
    public void Return_the_log_in_view_when_the_authentication_failed() {}

    [Test]
    public void Redirect_to_the_profile_when_the_authentication_passed() {}
}

I think this is a perfect example of why rigid naming conventions for unit tests are unattractive.

Your proposed scheme will only work when you have two method overloads: one with and one without parameters. It doesn't extend to the scenario where you have more than one overload with different parameters.

Personally I prefer a much looser naming convention that can be summarized as

[Action][Will|Should|Is|...][Result]

This gives me the flexibility to name my tests

SutIsPathResolutionCommand
ExecuteWithNullEvaluationContextWillThrow
ExecuteWillAddDefaultClaimsTransformationServiceWhenNoConnectionServiceIsAvailable

I must admit that I rarely read the name of the test anyway. Instead, I read the specification of what it does (ie the test code). The name is just not that important to me.

One option, which I don't particularly like, is to give the controller actions different names, but to then rename them using the ActionName attribute:

public ActionResult Login() {
    // ... code ...
    return View();
}

[HttpPost]
[ActionName("Login")]
public ActionResult LoginPost(... some params ...) {
    // ... more code ...
    return View();
}

This essentially substitutes one problem (unit test naming) with another problem (harder to read controller code). Nevertheless, you might find this pattern appealing since it does solve the stated problem.

I use a similar naming convention to the one in your question ie method_scenario_expected I think you should elaborate more on the "scenario" part - if you're passing parameters - let the reader know what is speacial about them.

Keep in mind that naming your tests this way is more "TDD oreinted" and no BDD - BDD tests names should be about rules and "behaviors:.

If you feel that the current naming convention does not hwlp the code readability - feel free to experiment around and find what works for you.

I may not be answering your question, but I want to share what I do. I don't follow specific naming convention, but I try to give names which explains what test method is trying to test. Some cases where I need more explanation I add description [Test("This test evaluates how many questions were answered by specific user")].

One thing to make sure is the tests are more readable and quickly understandable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM