views:

172

answers:

5

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?

+1  A: 

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 (i.e. the test code). The name is just not that important to me.

Mark Seemann
+1  A: 

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() {}
}
Thomas Eyde
+1  A: 

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.

Eilon
A: 

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.

mujahidkhaleel
+1  A: 

I use a similar naming convention to the one in your question i.e. *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.

Dror Helper