我正在为一项服务进行一些测试自动化,并想出了一种巧妙的方法来将一些常见的设置和验证汇总到一个“会话”类中。
从概念上讲,测试用例可能如下所示:
using (var managerSession = new Session(managerRole))
{
// A manager puts some items in warehouse
}
using (var employeeSession = new Session(employeeRole))
{
// An employee moves items from warehouse to store
}
using (var customerSession = new Session(customerRole))
{
// A customer can buy items from the store
}
在 Session 对象构造函数中,我使用每个角色的适当身份验证等设置到我正在测试的服务的连接,并且在会话 Dispose() 方法中,我有一个公共验证块,例如,检查没有服务器端错误或在会话生命周期内发出警告。
现在,当然,这有点滥用 IDispose 模式,如果 using 块中的测试代码抛出异常并且验证块也抛出异常,则第二个异常将掩盖第一个异常。
从概念上讲,如果我们有这种情况:
using (var managerSession = new Session(managerRole))
{
Assert.IsTrue(managerSession.DoJob(), "Manager did not do his job");
}
...并且断言失败或对 managerSession.DoJob() 的调用引发异常,那么我希望 Session Dispose() 方法跳过验证块,即
public void Dispose()
{
if (NoExceptionThrown())
{
Assert.IsFalse(this.serviceConnection.HasErrors(), "Service connection has errors");
}
this.serviceConnection.Dispose();
}
...这样测试方法永远不会因“服务连接有错误”而失败,如果它实际上因“经理没有完成他的工作”而失败
我的问题是:这里是否有可能实现“NoExceptionThrown()”方法?是否有一些可以检查的全局属性,或者隐藏在 Thread.CurrentThread 中的东西可以使用?
更新:
我的问题不是如何重构这个:-)
我当然可以改用这种模式:
Session.ForRole(managerRole, (session) => { /* Test code here */ });
使用静态方法 ForRole() 定义如下
public static void ForRole(Role r, Action<Session> code)
{
var session = new Session(r);
try
{
code(session);
Assert.IsFalse(session.serviceConnection.HasErrors());
}
finally
{
session.Dispose();
}
}
但我很好奇是否存在某种方式来获取如上所述的异常状态。