适当的单元测试:测试没有[可访问]状态或返回值的方法

jbu*_*jbu 7 unit-testing

我对单元测试有些新意.关于正确测试的一件事(现在)让我感到困惑.

例如,如果主方法没有状态且只有控制台输出,那么如何测试它?像这样,myServer方法和状态是私有的吗?

 public static void main(String[] args)
 {
     Server myServer = new Server()
     if(myServer.start())
          System.out.println("started");
     else
          System.out.println("failed"); 
 }
Run Code Online (Sandbox Code Playgroud)

我不想更改我的代码并公开我的服务器方法和状态以使它们公开.

注意,我不是问如何测试myServer.start(),我问的是如何测试main()本身.

请告诉我.

谢谢你们,jbu

Gis*_*shu 8

主要方法应该非常薄,只是让球滚动.因此通常没有经过测试 例如.net Winforms app主要方法可能包含

static void Main()
{
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new MainWindow());
}
Run Code Online (Sandbox Code Playgroud)

如果你的主要方法做了很多事情,可以考虑提取一个方法(如果需要的话,提到一个新类).例如,如下所示...(没有JavaIDE方便.. foll .net代码应该很容易翻译)

static void Main()
{
  new MainApp().Run();
}
Run Code Online (Sandbox Code Playgroud)

现在如果Run可以测试..主要也被覆盖.让我们看看MainApp.重构了启动服务器将结果记录为2个方法的2个任务.

public class MainApp
{
  private Server m_Server;
  public MainApp():this(new Server())
  {}
  public MainApp(Server s)
  {  m_Server = s;      }

  public void Run()
  {  Log(LaunchServer());  }

  private string LaunchServer()
  {  return (m_Server.start() ? "started" : "failed");        }

  protected virtual void Log(string sMessage)
  {  System.Console.WriteLine(sMessage);        }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们看一下测试代码......我将使用"子类和覆盖"技巧来缓存结果,如下所示.(你也可以根据口味使用Mocks ..)

public class FakeApp : MainApp
{
  private string sLastLoggedMessage;

  public FakeApp(Server s) : base(s) { }

  public string getLastLoggedMessage()
  {  return sLastLoggedMessage;        }

  protected override void Log(string sMessage)
  {  sLastLoggedMessage = sMessage;        }
}
Run Code Online (Sandbox Code Playgroud)

现在的考验是微不足道的

[TestFixture]
public class TestMainApp
{
  [Test]
  public void TestRun()
  {
    Server s = new Server();
    FakeApp f = new FakeApp(s);

    f.Run();

    Assert.AreEqual("started", f.getLastLoggedMessage());
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您不能根据需要强制Server.start()成功或失败.您可以创建一个FakeServer ..子类并覆盖start()以返回固定值.

如果方法有效,可以对其进行测试.如果没有,它应该不复存在.重构它.HTH


cle*_*tus 4

您(通常)不会对 main() 方法进行单元测试。在您的情况下,您对服务器类(可能还有其他类)进行单元测试,即测试它的公共接口。