如何在不弄乱单元测试的情况下使用静态变量?

时间:2017-05-13 23:09:01

标签: c# unit-testing oop

我有一个用户类 - 代码如下:

public class User
    {
        private int userID;
        private static int nextID = 99;
        private String firstName;
        private String lastName;
        private String email;
        private String password;
        private String fullName;

        public User()
        {
        }

        public User(String firstName, String lastName, String email, String password)
        {
            userID = nextID + 1;
            nextID++;
            this.firstName = firstName;
            this.lastName = lastName;
            fullName = firstName + " " + lastName;
            this.email = email;
            this.password = password;
        }

我想为用户提供一个唯一的UserID,每次实例化用户时都会递增。

我尝试使用静态int NextID来保存下一个对象的UserID,并在每次使用后在构造函数中将其递增。

然而,当我尝试这个时,它搞砸了我的单元测试,当我运行所有测试时它们中的一些失败但是它们在单独运行时仍然通过。

有没有人知道如何在不搞乱我的单元测试的情况下实现这个目标?

2 个答案:

答案 0 :(得分:3)

这看起来像是一个设计问题。

例如,尝试分离所涉及的类的关注点。

public interface IUserIdManager {
    int GetNextId();
}

public interface IUserFactory {
    User Create();
    User Create(String firstName, String lastName, String email, String password);
}

让用户管理器实现依赖于创建实例时要使用的id管理器。

public class UserFactory : IUserFactory {
    private readonly IUserIdManager ids;
    public UserFactory(IUserIdManager ids) {
        this.ids = ids;
    }

    public User Create() { 
        var user = new User();
        user.UserId = ids.GetNextId();
        return user;
    }

    public User Create(String firstName, String lastName, String email, String password) { 
        var user = new User(firstName, lastName, email, password);
        user.UserId = ids.GetNextId();
        return user;
    }
}

用户类不应该关心创建自己的id。这不是它的责任。它应该保持精简,作为一个简单的POCO /模型来保存数据。

答案 1 :(得分:1)

根据@Nkosi上面的答案,在此处发布我的生产代码。已经给@Nkosi提供了回答问题的功劳,但只是想展示解决方案代码并说它有效。另外,感谢所有人的评论,这对我帮助很大!

public class UserIDGenerator : IUserIDGenerator
{
    private int nextUserID = 100;

    public int getNextUserID()
    {
        return nextUserID++;
    }
}

public class UserAdministration : IUserAdministration
{
    private List<User> users = new List<User>();

    private IUserIDGenerator userIDGenerator;

    public UserAdministration(IUserIDGenerator userIDGenerator)
    {
        this.userIDGenerator = userIDGenerator;
    }

    public bool addUser(String firstName, String lastName, String email, String password)
    {
        users.Add(new User(userIDGenerator.getNextUserID(), firstName, lastName, email, password));
        return true;
    }
}