WCF Webプログラミングモデルの学習テスト Part3
今日はWCF 配信の学習テスト。AtomフィードとRSSフィードをどのように提供するかについて。
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Syndication; using System.ServiceModel.Web; using System.Xml; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace LearningWCFTests { [TestClass] public class SyndicationFeedTest { ... [ServiceContract] public interface ICustomers { [OperationContract] [WebGet(UriTemplate = "customers?format={format}")] [ServiceKnownType(typeof(Atom10FeedFormatter))] [ServiceKnownType(typeof(Rss20FeedFormatter))] SyndicationFeedFormatter GetCustomers(string format); [OperationContract] [WebGet(UriTemplate = "customers/{id}?format={format}")] [ServiceKnownType(typeof(Atom10FeedFormatter))] [ServiceKnownType(typeof(Rss20FeedFormatter))] SyndicationFeedFormatter GetCustomer(string id, string format); } [DataContract] public class Customer { [DataMember] public string Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public string Address { get; set; } public override string ToString() { return String.Format("{0}, {1}, {2}", Id, Name, Address); } } public class Customers : ICustomers { private List<Customer> customers_ = new List<Customer>() { new Customer() { Id = "1", Name = "Alice", Address = "123 Pike Place" }, new Customer() { Id = "2", Name = "Bob", Address = "12323 Lake Shore Drive" }, new Customer() { Id = "3", Name = "John", Address = "4545 Wacker Drive" } }; public SyndicationFeedFormatter GetCustomers(string format) { return CreateFeedFormatterFrom(customers_, format); } public SyndicationFeedFormatter GetCustomer(string id, string format) { return CreateFeedFormatterFrom( from customer in customers_ where customer.Id == id select customer, format); } private SyndicationFeedFormatter CreateFeedFormatterFrom(IEnumerable<Customer> customers, string format) { UriTemplateMatch match = WebOperationContext.Current.IncomingRequest.UriTemplateMatch; UriTemplate template = new UriTemplate("customers"); SyndicationFeed feed = new SyndicationFeed() { Id = template.BindByPosition(match.BaseUri).ToString(), Title = SyndicationContent.CreatePlaintextContent("Customers"), LastUpdatedTime = DateTimeOffset.Now }; feed.Links.Add(new SyndicationLink() { Uri = template.BindByPosition(match.BaseUri), RelationshipType = "self", Title = "Customers" }); feed.Items = from customer in customers select GetSyndicationItemFrom(customer); if (format == "atom") return new Atom10FeedFormatter(feed); else return new Rss20FeedFormatter(feed); } private SyndicationItem GetSyndicationItemFrom(Customer customer) { UriTemplateMatch match = WebOperationContext.Current.IncomingRequest.UriTemplateMatch; UriTemplate template = new UriTemplate("customer/{id}"); SyndicationItem item = new SyndicationItem() { Id = template.BindByPosition(match.BaseUri, customer.Id).ToString(), LastUpdatedTime = DateTimeOffset.Now, Content = SyndicationContent.CreateXmlContent(customer) }; SyndicationLink link = new SyndicationLink() { Uri = template.BindByPosition(match.BaseUri, customer.Id), RelationshipType = "edit", Title = "Customers" }; item.Links.Add(link); return item; } } private static readonly Uri HostBaseUri = new Uri("http://localhost:8000"); private static readonly Uri ClientBaseUri = new Uri("http://localhost:8000"); private WebServiceHost host_; [TestInitialize] public void サービスホスティングの開始() { host_ = new WebServiceHost(typeof(Customers), HostBaseUri); host_.Open(); } [TestCleanup] public void サービスホスティングの終了() { if (host_.State != CommunicationState.Closed) host_.Close(); } [TestMethod] public void Atom形式で取得したフィードからCustomerの一覧を取得できるべき() { UriTemplate template = new UriTemplate("customers?format={format}"); XmlReader reader = XmlReader.Create(template.BindByPosition(ClientBaseUri, "atom").ToString()); SyndicationFeed feed = SyndicationFeed.Load(reader); Assert.AreEqual<string>("Customers", feed.Title.Text); Assert.AreEqual<string>("http://localhost:8000/customers", feed.Id); Assert.AreEqual<int>(1, feed.Links.Count); Assert.AreEqual<Uri>(new Uri("http://localhost:8000/customers"), feed.Links[0].Uri); Assert.AreEqual<string>("self", feed.Links[0].RelationshipType); Assert.AreEqual<string>("Customers", feed.Links[0].Title); Assert.AreEqual<int>(3, feed.Items.Count()); XmlSyndicationContent aliceContent = feed.Items.ElementAt(0).Content as XmlSyndicationContent; Customer alice = aliceContent.ReadContent<Customer>(); Assert.AreEqual<string>("1, Alice, 123 Pike Place", alice.ToString()); XmlSyndicationContent bobContent = feed.Items.ElementAt(1).Content as XmlSyndicationContent; Customer bob = bobContent.ReadContent<Customer>(); Assert.AreEqual<string>("2, Bob, 12323 Lake Shore Drive", bob.ToString()); XmlSyndicationContent johnContent = feed.Items.ElementAt(2).Content as XmlSyndicationContent; Customer john = johnContent.ReadContent<Customer>(); Assert.AreEqual<string>("3, John, 4545 Wacker Drive", john.ToString()); } [TestMethod] public void RSS形式で取得したフィードからCustomerの一覧を取得できるべき() { UriTemplate template = new UriTemplate("customers?format={format}"); XmlReader reader = XmlReader.Create(template.BindByPosition(ClientBaseUri, "rss").ToString()); SyndicationFeed feed = SyndicationFeed.Load(reader); Assert.AreEqual<string>("Customers", feed.Title.Text); Assert.AreEqual<string>("http://localhost:8000/customers", feed.Id); Assert.AreEqual<int>(1, feed.Links.Count); Assert.AreEqual<Uri>(new Uri("http://localhost:8000/customers"), feed.Links[0].Uri); Assert.AreEqual<string>("self", feed.Links[0].RelationshipType); Assert.AreEqual<string>("Customers", feed.Links[0].Title); Assert.AreEqual<int>(3, feed.Items.Count()); XmlSyndicationContent aliceContent = feed.Items.ElementAt(0).Content as XmlSyndicationContent; Customer alice = aliceContent.ReadContent<Customer>(); Assert.AreEqual<string>("1, Alice, 123 Pike Place", alice.ToString()); XmlSyndicationContent bobContent = feed.Items.ElementAt(1).Content as XmlSyndicationContent; Customer bob = bobContent.ReadContent<Customer>(); Assert.AreEqual<string>("2, Bob, 12323 Lake Shore Drive", bob.ToString()); XmlSyndicationContent johnContent = feed.Items.ElementAt(2).Content as XmlSyndicationContent; Customer john = johnContent.ReadContent<Customer>(); Assert.AreEqual<string>("3, John, 4545 Wacker Drive", john.ToString()); } [TestMethod] public void Atom形式で取得したフィードからCustomerを取得できるべき() { UriTemplate template = new UriTemplate("customers/1?format={format}"); XmlReader reader = XmlReader.Create(template.BindByPosition(ClientBaseUri, "atom").ToString()); SyndicationFeed feed = SyndicationFeed.Load(reader); Assert.AreEqual<string>("Customers", feed.Title.Text); Assert.AreEqual<string>("http://localhost:8000/customers", feed.Id); Assert.AreEqual<int>(1, feed.Links.Count); Assert.AreEqual<Uri>(new Uri("http://localhost:8000/customers"), feed.Links[0].Uri); Assert.AreEqual<string>("self", feed.Links[0].RelationshipType); Assert.AreEqual<string>("Customers", feed.Links[0].Title); Assert.AreEqual<int>(1, feed.Items.Count()); XmlSyndicationContent aliceContent = feed.Items.First().Content as XmlSyndicationContent; Customer alice = aliceContent.ReadContent<Customer>(); Assert.AreEqual<string>("1, Alice, 123 Pike Place", alice.ToString()); } [TestMethod] public void RSS形式で取得したフィードからCustomerを取得できるべき() { UriTemplate template = new UriTemplate("customers/1?format={format}"); XmlReader reader = XmlReader.Create(template.BindByPosition(ClientBaseUri, "rss").ToString()); SyndicationFeed feed = SyndicationFeed.Load(reader); Assert.AreEqual<string>("Customers", feed.Title.Text); Assert.AreEqual<string>("http://localhost:8000/customers", feed.Id); Assert.AreEqual<int>(1, feed.Links.Count); Assert.AreEqual<Uri>(new Uri("http://localhost:8000/customers"), feed.Links[0].Uri); Assert.AreEqual<string>("self", feed.Links[0].RelationshipType); Assert.AreEqual<string>("Customers", feed.Links[0].Title); Assert.AreEqual<int>(1, feed.Items.Count()); XmlSyndicationContent aliceContent = feed.Items.First().Content as XmlSyndicationContent; Customer alice = aliceContent.ReadContent<Customer>(); Assert.AreEqual<string>("1, Alice, 123 Pike Place", alice.ToString()); } } }
最初のテストで出力されるAtom
<feed xmlns="http://www.w3.org/2005/Atom"> <title type="text">Customers</title> <id>http://localhost:8000/customers</id> <updated>2008-02-03T02:52:12+09:00</updated> <link rel="self" title="Customers" href="http://localhost:8000/customers"/> <entry> <id>http://localhost:8000/customer/1</id> <title type="text"/> <updated>2008-02-03T02:52:12+09:00</updated> <link rel="edit" title="Customers" href="http://localhost:8000/customer/1"/> <content type="text/xml"> <SyndicationFeedTest.Customer xmlns="http://schemas.datacontract.org/2004/07/LearningWCFTests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Address>123 Pike Place</Address> <Id>1</Id> <Name>Alice</Name> </SyndicationFeedTest.Customer> </content> </entry> <entry> <id>http://localhost:8000/customer/2</id> <title type="text"/> <updated>2008-02-03T02:52:12+09:00</updated> <link rel="edit" title="Customers" href="http://localhost:8000/customer/2"/> <content type="text/xml"> <SyndicationFeedTest.Customer xmlns="http://schemas.datacontract.org/2004/07/LearningWCFTests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Address>12323 Lake Shore Drive</Address> <Id>2</Id> <Name>Bob</Name> </SyndicationFeedTest.Customer> </content> </entry> <entry> <id>http://localhost:8000/customer/3</id> <title type="text"/> <updated>2008-02-03T02:52:12+09:00</updated> <link rel="edit" title="Customers" href="http://localhost:8000/customer/3"/> <content type="text/xml"> <SyndicationFeedTest.Customer xmlns="http://schemas.datacontract.org/2004/07/LearningWCFTests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Address>4545 Wacker Drive</Address> <Id>3</Id> <Name>John</Name> </SyndicationFeedTest.Customer> </content> </entry> </feed>
2番目のテストで出力されるRSS
<rss version="2.0" xmlns:a10="http://www.w3.org/2005/Atom"> <channel> <title>Customers</title> <description/> <lastBuildDate>Sun, 03 Feb 2008 02:52:12 +0900</lastBuildDate> <a10:id>http://localhost:8000/customers</a10:id> <a10:link rel="self" title="Customers" href="http://localhost:8000/customers"/> <item> <guid isPermaLink="false">http://localhost:8000/customer/1</guid> <description/> <a10:link rel="edit" title="Customers" href="http://localhost:8000/customer/1"/> <a10:updated>2008-02-03T02:52:12+09:00</a10:updated> <a10:content type="text/xml"> <SyndicationFeedTest.Customer xmlns="http://schemas.datacontract.org/2004/07/LearningWCFTests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Address>123 Pike Place</Address> <Id>1</Id> <Name>Alice</Name> </SyndicationFeedTest.Customer> </a10:content> </item> <item> <guid isPermaLink="false">http://localhost:8000/customer/2</guid> <description/> <a10:link rel="edit" title="Customers" href="http://localhost:8000/customer/2"/> <a10:updated>2008-02-03T02:52:12+09:00</a10:updated> <a10:content type="text/xml"> <SyndicationFeedTest.Customer xmlns="http://schemas.datacontract.org/2004/07/LearningWCFTests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Address>12323 Lake Shore Drive</Address> <Id>2</Id> <Name>Bob</Name> </SyndicationFeedTest.Customer> </a10:content> </item> <item> <guid isPermaLink="false">http://localhost:8000/customer/3</guid> <description/> <a10:link rel="edit" title="Customers" href="http://localhost:8000/customer/3"/> <a10:updated>2008-02-03T02:52:12+09:00</a10:updated> <a10:content type="text/xml"> <SyndicationFeedTest.Customer xmlns="http://schemas.datacontract.org/2004/07/LearningWCFTests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Address>4545 Wacker Drive</Address> <Id>3</Id> <Name>John</Name> </SyndicationFeedTest.Customer> </a10:content> </item> </channel> </rss>