NUnit:如何在C#中测试带有“ref”参数的私有方法

3
我有一个私有方法,如下所示:
int void SomeMethod(ref string theStr)
{
   // Some Implementation
}

如何为这个方法编写单元测试用例。
4个回答

7

一个方法是void类型但需要使用ref参数似乎有点毫无意义。将其改为返回一个字符串可能更加合理:

public class FooBar {
 internal string SomeMethod(ref string theStr) { 
    // Some Implementation 
    return theStr;
 }
}

我们还可以将其设为“内部”,并在AssemblyInfo.cs文件中指定“InternalVisibleTo”属性:
 [assembly: InternalsVisibleTo("Test.Assembly")]

这样做,SomeMethod 将表现得像是内部方法(即在其程序集外不可见),除了 Test.Assembly 会将其视为 public

无论是否需要传递 ref 参数,单元测试都非常简单。

[Test]
public void SomeMethodShouldReturnSomething() { 
   Foobar foobar = new Foobar();
   string actual;
   foobar.SomeMethod(ref actual);
   Assert.AreEqual("I'm the test your tests could smell like", actual);
}

谢谢您宝贵的纠正,但是我这里只是提供了一个代码片段,这并不是实际的代码。我的意图是想知道如何使用ref关键字测试私有方法。 - Nikhil Verma
1
@Nikhil:如果您不提供代表性代码,我们就无法轻易地确定哪些差异是相关的,哪些不是。 - Jon Skeet
@Nikhil Verma,如果该方法使用ref参数并不重要。请查看更新的代码。 - Igor Zevaka
我不喜欢这个的原因是,虽然我已经做了它,但你让主要程序集知道了测试程序集,因为你在它里面加上了“InternalsVisibleTo”。 - Grant Crofton
喜欢那个老香料的参考。 - Marcelo

1

我通常把方法设为 protected 并提供一个可测试的继承类。例如:

class Foo
{
  protected void SomeMethod(ref string theStr) { ... }
  ...
}

class TestableFoo
{
  public void TestableSomeMethod(ref string theStr)
  {
    base.SomeMethod(...);
  }
  ...

我认为你会发现有些答案会说“你不应该测试私有方法”,但是在某些情况下,我发现访问一些棘手的功能很有用。但是,在这种情况下,我也发现将函数提取到自己的单独可测试类中更好。你的情况可能会有所不同。


1
我实际上会认为你不是“不需要”测试私有方法,而是你不应该这样做,因为它不是类的公共契约的一部分。 - kyoryu
@kyoryu 非常正确。我通常会在单元测试内部方法和将功能带入另一个类之间划清界限,当没有足够的代码使其成为一个类时。对于这些情况,我很高兴削弱测试的纯度。 - Igor Zevaka
1
@kyoryu:我经常发现,测试类的内部比仅限于公共API更有效。如果它是一个相对较小的公共API,但有几个潜在的角落情况,白盒测试可以使测试这些角落情况变得更容易,而无需设置公共API所需的其余部分。 - Jon Skeet
我同意你们所有人的观点。但在某些情况下,测试私有方法也是必要的。如果有人感兴趣,我可以举个例子。 - Nikhil Verma

0

我的问题是如何为具有引用参数的私有方法编写单元测试用例。

有些人说改变实现,这是不可能的。也许我在代码片段中给出了一些错误的实现,但那不是我的意图。

有些人说不需要测试私有方法。但在某些情况下,需要测试这些方法,例如在某些安全代码中。

答案是:我需要使用反射并从nunit设置setnamedparameterAction。我需要明确指定特定参数是ref。


0

如果测试很重要,也许你应该将其公开并完成它。尽管我意识到这并没有完全回答你的问题。

并不是每个人都同意仅为测试而公开某些东西,但我认为这比其他一些选择更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接