开发者

c# unit test - naming convention for overloaded method tests

开发者 https://www.devze.com 2023-02-26 04:37 出处:网络
I have some simple extension methods in c# I\'m writing unit tests against. One of the extension methods is overloaded, so I\'m having trouble coming up with a reasonable naming convention for the uni

I have some simple extension methods in c# I'm writing unit tests against. One of the extension methods is overloaded, so I'm having trouble coming up with a reasonable naming convention for the unit tests.

Example overloaded method:

public static class StringExtensions
{
    public static List<string> ToList(this string value, char delimiter)
    {
        return ToList(value, new[] { delimiter });
    }

    public static List<string> ToList(this string value, char[] delimiterSet) { .. }
}

If I want to write two unit tests, one for each method that how would you name the tests? Normally I would use simply:

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTest

But with two methods of the same name, I'm struggling to find a good 开发者_JS百科convention..

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTest

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTestOverload

is horrendous.

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTestWithChar

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTestWithCharArray

based on parameter type is better but still pretty terrible.

Some may suggest to write one test method that targets both overloads, but I ideally want to have a 1:1 relationship with unit tests and methods, even if the overloads are currently chained. I don't want any assumptions made in the tests that the overloads are chained and pass-through.

How would you approach this?


Roy Osherove in his book, The Art of Unit Testing recommends naming conventions based on the behavior you're trying to test and not necessarily having a one-to-one mapping between production methods and test methods. So, as a simple example, assume I have a Stack class like so:

public class Stack
{
    public void Push(int value);
    public int Pop();
    public bool IsEmpty();
}

One way to write tests is to have three test methods:

[TestMethod]
public void PushTest

[TestMethod]
public void PopTest

[TestMethod]
public void IsEmptyTest

However, there's a better way to test that specifies the behaviors of the Stack class. The idea then is that you have a one-to-one mapping between class behaviors and test methods. So, one behavior is that IsEmpty on an empty stack returns true. Another is that pushing one element makes the stack not empty. I'd then write tests in the Arrange/Act/Assert format according to these plain English sentences specifying these behaviors in the format:

MethodName_StateOfTheObject_ExpectedResult

So for the behaviors mentioned above:

[TestMethod]
IsEmpty_OnEmptyStack_ReturnsTrue

[TestMethod]
Push_OnEmptyStack_MakesStackNotEmpty

I would encourage you to think about the behaviors you're trying to test in on the methods above and then map those behaviors to tests. For example:

[TestMethod]
ToList_OnEmptyString_ReturnsEmptyList

[TestMethod]
ToList_OnStringWithDelimiters_ReturnsListWithTokensSeparatedByDelemiter

[TestMethod]
ToList_OnStringWithoutDelimiters_ReturnsListWithOneString

More information here


I tend to go for the latter, though less based on the parameters being passed in and more on the actual functionality being tested.

So not:

  • TestFunctionWithListOfNumbers
  • and TestFunctionWithListOfStrings

but perhaps:

  • TestFunctionWithStudentIDs
  • and TestFunctionWithStudentNames


I tend to write test names in a more Given, When , Then way. This makes the test name verbose but it tells me what the function being tested was intending to do. So in your case i would have tests as

[TestMethod]
public void GivenSingleCharDelimeter_ToList_Returnsxxx()
[TestMethod]
public void GivenCharArrayDelimeter_ToList_Returnsxxx()
0

精彩评论

暂无评论...
验证码 换一张
取 消