简体   繁体   English

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

[英]Mocking xml file for unit testing with Rhinomocks

I want to mock xml used as below for unit tests.I am using Rhinomocks framework for mocking.How can I unit test my methods by not using the actual xml file.Do I have to change my code structure. 我想模拟如下用于单元测试的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();
    }

UPDATED: 更新:

I've modified your MyService class to have an overloaded constructor, which accepts Func<string, XDocument> to load an XDocument, and also Func<string> to resolve the value that corresponds to HostingEnvironment.ApplicationPhysicalPath . 我修改了MyService类,使其具有重载的构造函数,该构造函数接受Func<string, XDocument>加载XDocument,还接受Func<string>解析与HostingEnvironment.ApplicationPhysicalPath相对应的值。 When the default constructor is called, the same call to XDocument.Load is performed, and likewise for using HostingEnvironment.ApplicationPhysicalPath in building the path to the xml and xsd files. 调用默认构造函数时,将对XDocument.Load进行相同的调用,同样使用HostingEnvironment.ApplicationPhysicalPath来构建xml和xsd文件的路径。

However in an unit test you could call the other constructor like this: 但是,在单元测试中,您可以像这样调用其他构造函数:

        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);

You could also expose the XDocument on the Service, perhaps through a readonly property and check that the XDocument represents the Mocked xml. 您也可以通过只读属性在服务上公开XDocument,并检查XDocument是否表示Mocked xml。

MyService: 为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);
}

} }

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

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM