如何使用Rust for Windows API创建模拟Web::SyndicationFeed以进行单元测试

kadbb459  于 4个月前  发布在  Windows
关注(0)|答案(1)|浏览(36)

我从微软网站上的Rust for Windows RSS reader示例开始。它可以像预期的那样工作,但相当简单。我想扩展这个示例,把它变成有用的东西,并创建一个包括单元测试的示例项目。
我的应用程序代码确实像预期的那样工作。由于网络问题是常见的错误,我构造了main,以便检索提要的外部调用在一个函数中,解析提要的代码(如果返回一个)在另一个函数中。

fn check_syndication(client: &SyndicationClient) -> Result<SyndicationFeed> {
    let uri = Uri::CreateUri(h!("https://rpilocator.com/feed"))?;
    client.RetrieveFeedAsync(&uri)?.get()
}

fn parse_syndication(syndication_feed: SyndicationFeed) -> Vec<String> {
    let feed_items: IVector<SyndicationItem> = syndication_feed.Items().unwrap();

    feed_items
        .into_iter()
        .map(|item| item.Title().unwrap().Text().unwrap().to_string())
        .collect::<Vec<String>>()
}

字符串
这个想法是创建一个mock SyndicationFeed对象,然后像这样将其传递到我的parse_syndication()函数中:

#[test]
fn verify_parse_syndication() {
   let mock_uri = Uri::CreateUri(h!("https://mock_url.com")).unwrap();
   let mock_feed = SyndicationFeed::CreateSyndicationFeed(
      &HSTRING::from("Mock Title"),
      &HSTRING::from("Mock Subtitle"),
      &mock_uri,
   ).unwrap();
   
   let output = parse_syndication(mock_feed);
   assert_eq!(output.len(), 1);
}


虽然这个测试确实编译并创建了一个空的SyndicationFeed,但我还没有弄清楚如何填充它,以便SyndicationFeed.Items包含一个模拟的项目列表。

IVector<SyndicationItem>


The full source code on GitHub
SyndicationFeed文档并没有指出有任何类型的add()insert()功能。CreateSyndicationFeed()函数似乎没有提供一种方法来初始化SyndicationFeed与数据。我还没有找到其他的例子,创建一个在我的搜索GitHub,SO,或者一般的谷歌。我还搜索了工厂模式和API中其他类似类型对象的创建。
我确实尝试了一种不同的方法,在xml文件中创建了一个模拟RSS提要。然后我创建了一个指向本地资源的URI对象,并将其作为RetrieveFeedAsync()调用的输入。不幸的是,我也无法使其工作。混合URI语法中的正斜杠和pathbuf中的反斜杠存在多个问题。即使是本地资源的硬编码字符串也会失败打开文件。我最终放弃了这种方法。

d4so4syb

d4so4syb1#

正如IInspectable建议的那样,我能够生成一个带有String的mockXmlDocument,并调用SyndicationFeed::LoadFromXml来获得预期的SyndicationFeed输出,以便进行测试。

mod tests {
    use super::*;
    use windows::Data::Xml::Dom::XmlLoadSettings;
    pub struct XmlDoc {
        mock_xml: XmlDocument,
    }

    impl Default for XmlDoc {
        fn default() -> Self {
            let xml = String::from(
                "\
                <?xml version=\"1.0\" encoding=\"UTF-8\" ?><rss version=\"2.0\">\
                    <channel>\
                        <title>Mock Channel Title</title>\
                        <link>https://mockchannellink.com</link>\
                        <description>Mock Channel Description</description>\
                        <lastbuilddate>Fri, 08 Dec 2023 01:00:00 GMT</lastbuilddate>\
                        <item>\
                            <title>Mock Item Title</title>\
                            <description>Mock Item Description.</description>\
                            <link>https://mockitemlink.com</link>\
                            <guid ispermalink=\"false\">846c1690-b4ad-479a-95e3-2ca5ed4dfdbd</guid>\
                            <pubdate>Fri, 08 Dec 2023 01:00:00 GMT</pubdate>\
                        </item>\
                    </channel>\
                </rss>\
                ",
            );

            let xml_opts = XmlLoadSettings::new().expect("Opts creation failed");
            xml_opts
                .SetValidateOnParse(true)
                .expect("Set validate option failed");

            let mock_xml: XmlDocument = XmlDocument::new().expect("New XmlDoc::new failed");
            match mock_xml.LoadXmlWithSettings(&HSTRING::from(xml), &xml_opts) {
                Ok(doc) => doc,
                Err(e) => {
                    println!("LoadXml failed: {}", e.code());
                }
            };
            Self { mock_xml }
        }
    }

    #[test]
    fn verify_parse_syndication() {
        let xml_doc = XmlDoc::default().mock_xml;

        let mock_feed = SyndicationFeed::new().expect("New SyndicationFeed failed");
        mock_feed
            .LoadFromXml(&xml_doc)
            .expect("Load from xml failed");
        let output = parse_syndication(mock_feed);
        assert_eq!(output.len(), 1);
    }
}

字符串

相关问题