我正在与另一位开发人员合作开发一个开源项目。我正在进行需要读取默认自定义xml配置文件的单元测试。我只保证回购中路径的一部分将在他的机器上。如何重写此测试以使其可移植?每次我们将代码检入repo时,我都不希望测试开始失败。
public class ConfigurationTests
{
[TestMethod]
public void ConfigurationLoads()
{
//todo: how do I make this test portable?
const string configFile = @"C:\Users\Christopher\Source\Repos\RetailCoderVBE\RetailCoder.VBE\Config\rubberduck.config";
var deserializer = new XmlSerializer(typeof(Rubberduck.Config.Configuration));
using (StreamReader reader = new StreamReader(configFile))
{
Rubberduck.Config.Configuration config = (Rubberduck.Config.Configuration)deserializer.Deserialize(reader);
Assert.IsNotNull(config);
}
}
}
这是我保证其他开发人员将拥有的路径的一部分。在此之前我需要以某种方式动态获取。
\RetailCoderVBE\RetailCoder.VBE\Config\rubberduck.config
答案 0 :(得分:3)
您应该做的是创建文件系统的接口并在测试中模拟它。访问真实文件系统的这个接口的实现你无法测试,所以它必须尽可能简单。由于XmlSerializer.Deserialize方法接受Stream,因此您的接口可以返回Stream。
public interface IFileAccess
{
Stream GetFileStream(string fileName);
}
public class RealFileAccess : IFileAccess
{
public Stream GetFileStream(string fileName)
{
....
}
}
public class ConfigLoader
{
Rubberduck.Config.Configuration LoadConfiguration(IFileAccess fileAccess)
{
const string configFile = @"C:\Users\Christopher\Source\Repos\RetailCoderVBE\RetailCoder.VBE\Config\rubberduck.config";
var deserializer = new XmlSerializer(typeof(Rubberduck.Config.Configuration));
return (Rubberduck.Config.Configuration)deserializer.Deserialize(fileAccess.GetFileStream(configFile));
}
}
然后测试将是
[TestMethod]
public void ConfigurationLoads()
{
const string configFile = @"C:\Users\Christopher\Source\Repos\RetailCoderVBE\RetailCoder.VBE\Config\rubberduck.config";
IFileAccess fileAccess = Mock.Of<IFileAccess>();
// setup fileAccess
Rubberduck.Config.Configuration config = new ConfigLoader().LoadConfiguration(fileAccess);
Assert.IsNotNull(config);
Mock.Get(fileAccess).Verify(fa => fa.GetFileStream(configFile));
}
然后,您甚至可以检查是否使用正确的参数调用了GetFileStream。
答案 1 :(得分:2)
我正在进行需要读取默认自定义xml配置文件的单元测试。
以上强烈暗示它不是真正的单元测试。他们(理想情况下)独立于外部世界。 为什么需要读取配置文件?配置中存储了哪些信息?也许可以通过测试将带有虚拟信息的配置文件添加到项目中,或者通过某种界面将依赖项存根到文件系统。
这样做的标准方法看起来像
interface IConfigReader{
object GetValue(string key);
}
// later in code
var configDate = _reader.GetValue("ConnectionString");