使用Rhinomocks模拟xml文件以进行单元测试

时间:2014-07-03 02:35:14

标签: c# xml unit-testing rhino-mocks

我想模拟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();
    }

2 个答案:

答案 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();
}

}