gpt4 book ai didi

c# - 使用经过测试的内部方法对公共(public)方法进行单元测试

转载 作者:行者123 更新时间:2023-11-30 15:37:16 25 4
gpt4 key购买 nike

我发现自己经常陷入这种模式,我编写了一个由非常小的方法组成的类,这些方法完全由我的单元测试执行。然后我发现我需要构建另一个调用这些方法的方法,我必须为此编写一个更复杂的单元测试——一个简单的例子就可以说明问题:

namespace FooRequest
{
static public class Verifier
{
static public bool IsValid(string request)
{
return (!IsAllCaps(request) && !ContainsTheLetterB(request));
}

static internal bool IsAllCaps(string request)
{
return (request.Equals(request.ToUpper()));
}

static internal bool ContainsTheLetterB(string request)
{
return request.ToLower().Contains("b");
}
}
}

对于代码,我会编写单元测试来覆盖两个内部方法,如下所示:

namespace UnitTest
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using FooRequest;

public class VerifierTest
{
[TestClass]
public class ContainsTheLetterB
{
[TestMethod]
public void ShouldReturnTrueForStringContainsB()
{
Assert.IsTrue(Verifier.ContainsTheLetterB("burns"));
}

[TestMethod]
public void ShouldReturnFakseForStringDoesNotContainB()
{
Assert.IsFalse(Verifier.ContainsTheLetterB("urns"));
}
}

[TestClass]
public class IsAllCaps
{
[TestMethod]
public void ShouldReturnTrueForStringIsAllCaps()
{
Assert.IsTrue(Verifier.IsAllCaps("IAMALLCAPS"));
}

[TestMethod]
public void ShouldReturnFakseForStringDoesNotContainB()
{
Assert.IsFalse(Verifier.IsAllCaps("IAMnotALLCAPS"));
}
}
}
}

对于公共(public)方法,我真的只是想测试“如果你调用的方法返回 false,则返回 false”——这很烦人,我必须以这种方式设置输入以强制我的内部方法返回 true 或false – 我对该方法的测试不应该关心它调用的内部方法(对吧?)

    [TestClass]
public class IsValid
{
[TestMethod]
public void ShouldReturnFalseForInvalidStringBecauseContainsB()
{
Assert.IsFalse(Verifier.IsValid("b"));
}

[TestMethod]
public void ShouldReturnFalseForInvalidStringBecauseIsAllCaps()
{
Assert.IsFalse(Verifier.IsValid("CAPS"));
}

[TestMethod]
public void ShouldReturnTrueForValidString()
{
Assert.IsTrue(Verifier.IsValid("Hello"));
}
}

显然对于这个例子来说,这还不算太糟糕,但是当有很多内部方法并且输入配置起来很重要时,测试我的公共(public)“这个输入是否有效”方法就变得复杂了。

我应该为我所有的内部方法创建一个接口(interface)然后将其 stub 用于测试还是有更简洁的方法?

最佳答案

我正在输入评论,但它太大了。我认为您处于违反 SRP 的边缘,但您肯定违反了开放/封闭原则。如果您需要更改验证字符串的方式,则需要修改您的验证器类。

我的处理方式与@seldary 有点不同,但差别不大...

    public interface IStringRule
{
bool Matches(string request);
}

public class AllCapsRule : IStringRule
{
public bool Matches(string request)
{
//implement
}
}

public class IsContainingBRule : IStringRule
{
public bool Matches(string request)
{
//implement
}
}

public class Verifier
{
private List<IStringRule> Rules;

public Verifier(List<IStringRule> rules)
{
Rules = rules;
}

public bool IsValid(string request)
{
return (!Rules.Any(x=>x.Matches(request) == false));
}
}

现在您的验证程序对扩展开放,但对修改关闭。您可以根据需要添加任意数量的新规则,并且实现不会改变。测试验证器就像传递一些返回任意 true 和 false 值的模拟字符串规则一样简单,并确保验证器返回适当的结果。

每个 IStringRule 都会像您一样单独进行测试。

关于c# - 使用经过测试的内部方法对公共(public)方法进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12792593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com