一种选择是将不可测试的 UI 部分从可测试的业务逻辑中分离出来:
public string GetDirectory(string whereTo)
{
FolderBrowserDialog dialog = new FolderBrowserDialog { Description = whereTo };
DialogResult result = dialog.ShowDialog();
return GetDirectory(dialog.SelectedPath, result);
}
public string GetDirectory(string selectedPath, DialogResult result)
{
return result == DialogResult.OK ? selectedPath : string.Empty;
}
所以你只需测试第二种方法,这变得很容易。
另一种选择是使用 UI 组件的模拟/伪造。但是,FolderBrowserDialog 被密封,这使得这更难。
你可以做这样的事情,但这可能有点过头了。
首先,为您要使用的部分定义一个接口:
public interface IFolderBrowserDialogWrapper
{
DialogResult ShowDialog();
string SelectedPath { get; }
}
然后将真正的FolderBrowserDialog 包裹在你的新界面中:
public class FolderBrowserDialogWrapper : IFolderBrowserDialogWrapper
{
private readonly FolderBrowserDialog m_dialog;
public DialogResult ShowDialog()
{
return m_dialog.ShowDialog();
}
public string SelectedPath
{
get { return m_dialog.SelectedPath; }
}
public FolderBrowserDialogWrapper(FolderBrowserDialog dialog)
{
m_dialog = dialog;
}
}
并创建一个用于测试的假版本,它只返回传递给其构造函数的值:
public class FakeFolderBrowserDialogWrapper : IFolderBrowserDialogWrapper
{
private readonly DialogResult m_result;
private readonly string m_selectedPath;
public DialogResult ShowDialog()
{
return m_result;
}
public string SelectedPath
{
get { return m_selectedPath; }
}
public FakeFolderBrowserDialogWrapper(string selectedPath, DialogResult result)
{
m_selectedPath = selectedPath;
m_result = result;
}
}
那么您的方法可以使用FolderBrowserDialogWrapper 进行真正的对话:
public string GetDirectory(string whereTo)
{
var f = new FolderBrowserDialogWrapper(
new FolderBrowserDialog { Description = whereTo });
return GetDirectory(f);
}
public string GetDirectory(IFolderBrowserDialogWrapper dialog)
{
DialogResult result = dialog.ShowDialog();
return result == DialogResult.OK ? dialog.SelectedPath : string.Empty;
}
并且测试可以使用FakeFolderBrowserDialogWrapper 绕过 UI:
[Test]
public static void TestDirectoryFinderGetDirectoryWithOKExpectThePath()
{
const string expectedPath = @"C:\temp";
var dlg = new FakeFolderBrowserDialogWrapper(expectedPath, DialogResult.OK);
var df = new DirectoryFinder();
string result = df.GetDirectory(dlg);
Assert.That(result, Is.EqualTo(expectedPath));
}
[Test]
public static void TestDirectoryFinderGetDirectoryWithCancelExpectEmptyString()
{
const string expectedPath = @"C:\temp";
var dlg = new FakeFolderBrowserDialogWrapper(expectedPath, DialogResult.Cancel);
var df = new DirectoryFinder();
string result = df.GetDirectory(dlg);
Assert.That(result, Is.EqualTo(string.Empty));
}
但这可能有点过头了,除非您也在代码的其他地方创建了大量 FolderBrowserDialogs。