我对单元测试有些新意.关于正确测试的一件事(现在)让我感到困惑.
例如,如果主方法没有状态且只有控制台输出,那么如何测试它?像这样,myServer方法和状态是私有的吗?
public static void main(String[] args) { Server myServer = new Server() if(myServer.start()) System.out.println("started"); else System.out.println("failed"); }
我不想更改我的代码并公开我的服务器方法和状态以使它们公开.
注意,我不是问如何测试myServer.start(),我问的是如何测试main()本身.
请告诉我.
谢谢你们,jbu
主要方法应该非常薄,只是让球滚动.因此通常没有经过测试 例如.net Winforms app主要方法可能包含
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainWindow()); }
如果你的主要方法做了很多事情,可以考虑提取一个方法(如果需要的话,提到一个新类).例如,如下所示...(没有JavaIDE方便.. foll .net代码应该很容易翻译)
static void Main() { new MainApp().Run(); }
现在如果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); } }
现在让我们看一下测试代码......我将使用"子类和覆盖"技巧来缓存结果,如下所示.(你也可以根据口味使用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; } }
现在的考验是微不足道的
[TestFixture] public class TestMainApp { [Test] public void TestRun() { Server s = new Server(); FakeApp f = new FakeApp(s); f.Run(); Assert.AreEqual("started", f.getLastLoggedMessage()); } }
如果您不能根据需要强制Server.start()成功或失败.您可以创建一个FakeServer ..子类并覆盖start()以返回固定值.
如果方法有效,可以对其进行测试.如果没有,它应该不复存在.重构它.HTH