c# - 重复的单元测试可以吗?

标签 c# unit-testing

我有以下类(class)

public interface IAuthProvider
{
    string GenerateKey();
}

public class AuthProvider : IAuthProvider
{
    public string GenerateKey()
    {
        using (var rng = new RNGCryptoServiceProvider())
        {
            var data = new byte[16];
            rng.GetBytes(data);
            return BitConverter.ToString(data).Replace("-","");
        }
    }
}

我还有以下单元测试来配合它

[TestClass]
public class AuthProviderTests
{
    private AuthProvider _provider;
    private string _key;

    [TestInitialize]
    public void Initialize()
    {
        _provider = new AuthProvider();
        _key = _provider.GenerateKey();
    }

    [TestMethod]
    public void GenerateKey_key_length_is_32_characters()
    {
        Assert.AreEqual(32, _key.Length);
    }

    [TestMethod]
    public void GenerateKey_key_is_valid_uppercase_hexidecimal_string()
    {
        Assert.IsTrue(_key.All(c =>
            (c >= '0' && c <= '9') || 
            (c >= 'A' && c <= 'F')
        ));
    }

    [TestMethod]
    public void GenerateKey_keys_are_random()
    {
        var keys = new List<string>
            {
                _provider.GenerateKey(),
                _provider.GenerateKey(),
                _provider.GenerateKey(),
                _provider.GenerateKey(),
                _provider.GenerateKey()
            };

        var distinctCount = keys.Distinct().Count();

        Assert.AreEqual(5, distinctCount);
    }
}

一切都很好。然而,我需要创建一个名为GenerateSecret的方法(以及与之相伴的测试)。该方法的作用与GenerateKey()完全相同。

现在我想我应该创建一个名为GenerateRandomHexString(int bytes)的方法并将代码从GenerateKey复制到其中。然后对于GenerateKey和GenerateSecret我应该使用以下代码:

public interface IAuthProvider
{
    string GenerateKey();
    string GenerateSecret();
    string GenerateRandomHexString(int bytes);
}

public class AuthProvider : IAuthProvider
{
    public string GenerateKey()
    {
        return GenerateRandomHexString(16);
    }

    public string GenerateSecret()
    {
        return GenerateRandomHexString(16);
    }

    public string GenerateRandomHexString(int bytes)
    {
        using (var rng = new RNGCryptoServiceProvider())
        {
            var data = new byte[bytes];
            rng.GetBytes(data);
            return BitConverter.ToString(data).Replace("-","");
        }
    }
}

现在进行测试,我应该只为GenerateRandomHexString 方法编写测试,还是应该为GenerateSecret 和GenerateKey 编写测试(这将是几乎相同的测试)

最佳答案

为什么需要两个方法来做同样的事情?

无论如何,您应该编写单独的测试。

  • 通常单元测试应覆盖公共(public)接口(interface)而不是非公共(public)成员,并且如果您的GenerateHexString仅供其他方法使用,则它可能不应该是公共(public)的
  • 您的实现现在是相同的,但将来可能会有所不同。如果没有独特的测试用例,您可能会错过由某人更改这些实现之一而引入的重大更改
  • 最终您的测试不应该知道或关心代码的内部实现细节

TestCaseSource 属性可能对 nUnit 有所帮助。它将允许您为两种方法定义相同的测试用例,从而节省代码中的一些重复。

关于c# - 重复的单元测试可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14449817/

相关文章:

c# - 尝试 catch block 还是 bool 标志?

c# - 使用 Async/Await 重写我的 Utils 库的正确方法

c++ - 使用 Catch2 以全精度打印浮点值

angularjs - 在 AngularJS 应用程序中运行 Karma 单元测试时出现 "Unexpected request"错误

java - Mockito when().thenReturn() 在被测系统中不起作用

unit-testing - 在 Golang 中测试接受不返回值的回调函数的方法

c# - 判断事件窗口是否为 WPF 窗口

c# - C#中如何拦截http请求?

javascript - 将对象从 JavaScript 传递到 C#

python - 使用 unittest.mock 在 python 中修补 SMTP 客户端