-1

I'm new to unit testing and need some help. This example is only for me to learn, I'm not actually counting the number of users in a static variable when I clearly could just use the count property on the List data structure. Help me figure out how to get my original assertion that there are 3 users. Here is the code:

Class User

namespace TestStatic
{
    public class User
    {
        public string Name { get; set; }
        public int Dollars { get; set; }
        public static int Num_users { get; set; }

        public User(string name)
        {
            this.Name = name;
            Num_users++;
        }


        public int CalculateInterest(int interestRate)
        {
            return Dollars * interestRate;
        }
    }
}

Test using MSTest

namespace TestStaticUnitTest
{
    [TestClass]
    public class CalcInterest
    {
        [TestMethod]
        public void UserMoney()
        {
            // arrange
            User bob = new User("Bob");
            bob.Dollars = 24;

            // act
            int result = bob.CalculateInterest(6);

            // assert
            Assert.AreEqual(144, result);

            //cleanup?
        }

        [TestMethod]
        public void UserCount()
        {
            // arrange
            List<User> users = new List<User>(){ new User("Joe"), new User("Bob"), new User("Greg") };

            // act
            int userCount = User.Num_users;

            // assert
            Assert.AreEqual(3, userCount);
        }
    }
}

The result in the UserCount test fails because a fourth user exist. The user from the UserMoney test is still in memory. What should I do to get three users? Should I garbage collect the first Bob?

Also, I would think that a test that reaches into another test wouldn't be a good unit test. I know that could be an argument, but I'll take any advice from the community on this code. Thanks for the help.

Gregory M
  • 31
  • 1
  • 6
  • 1
    seems like you do not understand static fields ... just set it to 0 before list creation ... – Selvin May 02 '20 at 19:01
  • 2
    The “fix” would likely be to eliminate the static field entirely. It is brittle and hard to work with here. Instead of making a type “know” how many instances are created, use collections or a custom container (which support a count). – user2864740 May 02 '20 at 19:04
  • also `Num_users` is misleading ... it should be called `ConstructorCallsCount` – Selvin May 02 '20 at 19:05
  • @Selvin, you are correct. I just realized the the other day after a test question that static fields can be used in non-static classes. :) ha ha ha ha. Actually it isn't that funny, but for real, resetting it to 0 is a great idea. Thanks my man! – Gregory M May 02 '20 at 21:24
  • @user2864740 I'll definitely use collections to get the count. – Gregory M May 02 '20 at 21:29

1 Answers1

0

The obvious solution would be to remove the static counter. As you see, when you enter the second unit test method UserCount() the value of that counter is still 1 from the execution of the first unit test method UserMoney() before.

If you want to keep the counter (for learning purposes to see what's going on), you can use cleanup methods which will "reset" the environment before all or each unit test method. In this case you want to reset the counter to 0 for every unit test method execution. You do so by writing a method with the [TestInitialize] attribute:

[TestInitialize]
public void _Initialize() {
    User.Num_users = 0;
}

That way, each unit test runs with a "clean" state where the counter will be reset to 0 before the actual unit test method is executed.

You might want to look at Why does TestInitialize get fired for every test in my Visual Studio unit tests? to see how these attributes work.

Progman
  • 16,827
  • 6
  • 33
  • 48
  • I just tried the TestInitialize attribute and set the User.Num_users to 0. This works great, and I'm glad you told me about the TestInitialize. I read the link, too. ClassCleanup and the other attributes will be helpful once I get the hang of writing unit test. As you and others have pointed out, the static variable makes no sense here, and the unit test did exactly what was supposed to do: catch bugs (my faulty logic). Thanks so much for your help, Progman. – Gregory M May 02 '20 at 21:57