我想模拟xml用于单元测试。我正在使用Rhinomocks框架进行模拟。如何通过不使用实际的xml文件来单元测试我的方法。我必须更改我的代码结构。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MyService : IMyService
{
private readonly string mSchemaPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "App_Data",
"schema_0.1.xsd");
private readonly string mXmlPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "App_Data",
"MyDataRecords.xml");
private XDocument mXDocument;
public MyService()
{
try
{
//load xml document
mXDocument = XDocument.Load(mXmlPath);
if (mXDocument == null)
{
throw new Exception("Null returned while reading xml file");
}
}
catch (Exception e)
{
//my exception management code
}
}
public List<MyDataRecords> GetAllRecords()
{
////fetch records from xDocument
mXDocument.Save();
}
public void AddRecord(MyRecord record)
{
////add record
mXDocument.Save();
}
答案 0 :(得分:1)
更新:
我已经修改了MyService类,使其具有重载的构造函数,该构造函数接受Func<string, XDocument>
来加载XDocument,还Func<string>
来解析与HostingEnvironment.ApplicationPhysicalPath
对应的值。调用默认构造函数时,将执行对XDocument.Load的相同调用,同样也可以在构建xml和xsd文件的路径时使用HostingEnvironment.ApplicationPhysicalPath
。
但是在单元测试中,你可以像这样调用另一个构造函数:
const string mockDirectory = "TEST";
var expectedXmlPath = Path.Combine(mockDirectory, "App_Data", "MyDataRecords.xml");
string xmlPathPassed = "";
var service = new MyService(path =>
{
xmlPathPassed = path;
return XDocument.Parse("<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>");
},
() => mockDirectory);
Assert.Equal(expectedXmlPath, xmlPathPassed);
您也可以通过readonly属性公开服务上的XDocument,并检查XDocument是否代表Mocked xml。
为MyService:
public class MyService : IMyService
{
private const string AppDataDirectoryName = "App_Data";
private const string SchemaFileName = "schema_0.1.xsd";
private const string XmlFileName = "MyDataRecords.xml";
private readonly Func<string, XDocument> mdocumentLoader;
private readonly Func<string> mAppDataDirectoryBuilder;
private readonly string mSchemaPath = "";
private readonly string mXmlPath = "";
private XDocument mXDocument;
public MyService() : this(XDocument.Load, () => HostingEnvironment.ApplicationPhysicalPath)
{
}
public MyService(Func<string, XDocument> documentLoader, Func<string> appDataDirectoryBuilder)
{
mdocumentLoader = documentLoader;
mAppDataDirectoryBuilder = appDataDirectoryBuilder;
try
{
var baseDirectory = mAppDataDirectoryBuilder();
mSchemaPath = Path.Combine(baseDirectory, AppDataDirectoryName, SchemaFileName);
mXmlPath = Path.Combine(baseDirectory, AppDataDirectoryName, XmlFileName);
mXDocument = mdocumentLoader(mXmlPath);
if (mXDocument == null)
{
throw new Exception("Null returned while reading xml file");
}
}
catch (Exception e)
{
//my exception management code
}
}
public List<MyRecord> GetAllRecords()
{
////fetch records from xDocument
return null;
//mXDocument.Save();
}
public void AddRecord(MyRecord record)
{
////add record
// mXDocument.Save(record);
}
}
答案 1 :(得分:0)
[assembly: InternalsVisibleTo("MyService.UnitTests")]
public class MyService : IMyService
{
private readonly string mSchemaPath;
private readonly string mXmlPath;
public MyService()
: this(
Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "App_Data", "MyDataRecords.xml"),
Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "App_Data", "schema_0.1.xsd"))
{
}
internal MyService(string xmlPath,string schemaPath)
{
try
{
mXmlPath=xmlPath;
mSchemaPath=schemaPath;
//load xml document
mXDocument = Xdocument.Laod(mXmlPath);
if (mXDocument == null)
{
throw new Exception("Null returned while reading xml file");
}
}
catch (Exception e)
{
//my exception management code
}
}
public List<MyRecord> GetAllRecords()
{
////fetch records from xDocument
mXDocument.Save();
}
public void AddRecord(MyRecord record)
{
////add record
mXDocument.Save();
}
}