Discussion:
Mock XmlReader for Testing? Alternate approaches?
Steven Smith
2008-05-15 04:20:14 UTC
Permalink
I'm struggling to figure out how to test some code that relies on XmlReader
and RssFormatter. Here's the code, which is close to what I'm using in my
library:



XmlReader reader = XmlReader.Create

("http://localhost/MyWebSite/rssfeed.aspx");

Rss20FeedFormatter formatter =

new Rss20FeedFormatter();

formatter.ReadFrom(reader);

reader.Close();

Label3.Text = formatter.Feed.Title.Text;

Label5.Text = formatter.Feed.Copyright.Text;

DataList1.DataSource =

formatter.Feed.Items.Single().lin;

DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx



Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having *those* implement
interfaces which I can then use with mocks but that is a lot of trouble to
go through and I'm really hoping someone will tell me there is a better way.



Thoughts?



Steve





--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org
Roy Osherove
2008-05-15 04:49:22 UTC
Permalink
I'd suggest stubbing these out with Typemock.
Post by Steven Smith
I'm struggling to figure out how to test some code that relies on
XmlReader and RssFormatter. Here's the code, which is close to what I'm
XmlReader reader = XmlReader.Create
("http://localhost/MyWebSite/rssfeed.aspx");
Rss20FeedFormatter formatter =
new Rss20FeedFormatter();
formatter.ReadFrom(reader);
reader.Close();
Label3.Text = formatter.Feed.Title.Text;
Label5.Text = formatter.Feed.Copyright.Text;
DataList1.DataSource =
formatter.Feed.Items.Single().lin;
DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx
Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having **those**
implement interfaces which I can then use with mocks but that is a lot of
trouble to go through and I'm really hoping someone will tell me there is a
better way.
Thoughts?
Steve
--
Steven A Smith | ASP.NET MVP | Microsoft Regional Director
President, ASPAlliance LLC | http://aspalliance.com
--
Thanks,

Roy Osherove
www.TypeMock.com - Simplify Unit Testing

Author of "The Art Of Unit Testing" ( http://ArtOfUnitTesting.com )
www.ISerializable.com (blog)
Steven Smith
2008-05-15 13:15:44 UTC
Permalink
I should mention that my tests are currently using Rhino Mocks. Also this
sample code is from an article and isn't *exactly* my code, as my code is in
fact using MVC and has the feed gathering being done in a separate class
entirely from the web app.



What I really want to do is aggregate several feeds into one (ordered by
date posted), and be able to test that the merging and ordering is working
correctly given some test data that doesn't rely on the existence of any
particular URI or XML file. What I have now is an RssAggregator class which
has a property representing a collection of feeds, and a method that uses
XmlReader (as shown) to iterate through this feed collection and grab each
feed's posts. This functions but doesn't meet my testing criteria.



Looking for examples of XmlReader and unit tests didn't yield me much in my
searching, unfortunately.



Regards,

Steve



--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org



From: altdotnet-***@public.gmane.org [mailto:altdotnet-***@public.gmane.org] On Behalf
Of Roy Osherove
Sent: Thursday, May 15, 2008 12:49 AM
To: altdotnet-***@public.gmane.org
Subject: Re: [altdotnet] Mock XmlReader for Testing? Alternate approaches?



I'd suggest stubbing these out with Typemock.

On Thu, May 15, 2008 at 7:20 AM, Steven Smith <ssmith-i0bCTVip/***@public.gmane.org>
wrote:

I'm struggling to figure out how to test some code that relies on XmlReader
and RssFormatter. Here's the code, which is close to what I'm using in my
library:



XmlReader reader = XmlReader.Create

("http://localhost/MyWebSite/rssfeed.aspx");

Rss20FeedFormatter formatter =

new Rss20FeedFormatter();

formatter.ReadFrom(reader);

reader.Close();

Label3.Text = formatter.Feed.Title.Text;

Label5.Text = formatter.Feed.Copyright.Text;

DataList1.DataSource =

formatter.Feed.Items.Single().lin;

DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx



Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having *those* implement
interfaces which I can then use with mocks but that is a lot of trouble to
go through and I'm really hoping someone will tell me there is a better way.



Thoughts?



Steve





--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org
--
Thanks,

Roy Osherove
www.TypeMock.com - Simplify Unit Testing

Author of "The Art Of Unit Testing" ( http://ArtOfUnitTesting.com )
www.ISerializable.com (blog)
Roy Osherove
2008-05-15 04:52:02 UTC
Permalink
another thing you can do is refactor using "Adapt Parameter" so you'd end up
with a method like this:

void BindTo(IFeedDetails details)
{

Label3.Text = details.Title;

Label5.Text = details.copyright;

DataList1.DataSource =details.ToBindTo;

DataList1.DataBind();

}
Post by Steven Smith
I'm struggling to figure out how to test some code that relies on
XmlReader and RssFormatter. Here's the code, which is close to what I'm
XmlReader reader = XmlReader.Create
("http://localhost/MyWebSite/rssfeed.aspx");
Rss20FeedFormatter formatter =
new Rss20FeedFormatter();
formatter.ReadFrom(reader);
reader.Close();
Label3.Text = formatter.Feed.Title.Text;
Label5.Text = formatter.Feed.Copyright.Text;
DataList1.DataSource =
formatter.Feed.Items.Single().lin;
DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx
Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having **those**
implement interfaces which I can then use with mocks but that is a lot of
trouble to go through and I'm really hoping someone will tell me there is a
better way.
Thoughts?
Steve
--
Steven A Smith | ASP.NET MVP | Microsoft Regional Director
President, ASPAlliance LLC | http://aspalliance.com
--
Thanks,

Roy Osherove
www.TypeMock.com - Simplify Unit Testing

Author of "The Art Of Unit Testing" ( http://ArtOfUnitTesting.com )
www.ISerializable.com (blog)
Jeff Brown
2008-05-15 06:33:30 UTC
Permalink
There's no real need to mock the XmlReader or Rss20FeedFormatter themselves.
You should be able to trust that they do what they're supposed to. The
transformation being performed is quite simple and deterministic.

So the main thing I see is that you need to strip out the dependency on that
feed Url so that you can replace it with known static content.

You could of course rip the whole thing out into a service of some sort but
that may be overkill. At best, I'd suggest moving code like this into your
Controller instead of having it in the View. (But it looks like you're
doing ASP.Net.)


Or... you could always write an integration test instead (yet somehow
control what rssfeed.aspx produces). You'll probably want to do that
anyways at some level to make sure the whole thing works when all the pieces
are assembled.

An integration test may be slower and more brittle but it will give you
useful feedback just the same.

Jeff.

_____

From: altdotnet-***@public.gmane.org [mailto:altdotnet-***@public.gmane.org] On Behalf
Of Steven Smith
Sent: Wednesday, May 14, 2008 9:20 PM
To: altdotnet-***@public.gmane.org
Subject: [altdotnet] Mock XmlReader for Testing? Alternate approaches?



I'm struggling to figure out how to test some code that relies on XmlReader
and RssFormatter. Here's the code, which is close to what I'm using in my
library:



XmlReader reader = XmlReader.Create

("http://localhost/MyWebSite/rssfeed.aspx");

Rss20FeedFormatter formatter =

new Rss20FeedFormatter();

formatter.ReadFrom(reader);

reader.Close();

Label3.Text = formatter.Feed.Title.Text;

Label5.Text = formatter.Feed.Copyright.Text;

DataList1.DataSource =

formatter.Feed.Items.Single().lin;

DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx



Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having *those* implement
interfaces which I can then use with mocks but that is a lot of trouble to
go through and I'm really hoping someone will tell me there is a better way.



Thoughts?



Steve





--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org
Ben Hall
2008-05-15 08:51:12 UTC
Permalink
Hi,

You might find this post useful -
http://blog.benhall.me.uk/2007/10/how-to-unit-test-regex-and-technorati.html

I wrote it regarding how to process Technorati API response, however
RSS should have the same core concepts.

Hope you find it useful.

Ben
Post by Jeff Brown
There's no real need to mock the XmlReader or Rss20FeedFormatter
themselves. You should be able to trust that they do what they're supposed
to. The transformation being performed is quite simple and deterministic.
So the main thing I see is that you need to strip out the dependency on that
feed Url so that you can replace it with known static content.
You could of course rip the whole thing out into a service of some sort but
that may be overkill. At best, I'd suggest moving code like this into your
Controller instead of having it in the View. (But it looks like you're
doing ASP.Net.)
Or... you could always write an integration test instead (yet somehow
control what rssfeed.aspx produces). You'll probably want to do that
anyways at some level to make sure the whole thing works when all the pieces
are assembled.
An integration test may be slower and more brittle but it will give you
useful feedback just the same.
Jeff.
________________________________
Of Steven Smith
Sent: Wednesday, May 14, 2008 9:20 PM
Subject: [altdotnet] Mock XmlReader for Testing? Alternate approaches?
I'm struggling to figure out how to test some code that relies on XmlReader
and RssFormatter. Here's the code, which is close to what I'm using in my
XmlReader reader = XmlReader.Create
("http://localhost/MyWebSite/rssfeed.aspx");
Rss20FeedFormatter formatter =
new Rss20FeedFormatter();
formatter.ReadFrom(reader);
reader.Close();
Label3.Text = formatter.Feed.Title.Text;
Label5.Text = formatter.Feed.Copyright.Text;
DataList1.DataSource =
formatter.Feed.Items.Single().lin;
DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx
Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having *those* implement
interfaces which I can then use with mocks but that is a lot of trouble to
go through and I'm really hoping someone will tell me there is a better way.
Thoughts?
Steve
--
Steven A Smith | ASP.NET MVP | Microsoft Regional Director
President, ASPAlliance LLC | http://aspalliance.com
------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/altdotnet/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/altdotnet/join
(Yahoo! ID required)

<*> To change settings via email:
mailto:altdotnet-digest-***@public.gmane.org
mailto:altdotnet-fullfeatured-***@public.gmane.org

<*> To unsubscribe from this group, send an email to:
altdotnet-unsubscribe-***@public.gmane.org

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Steven Smith
2008-05-15 13:18:43 UTC
Permalink
Yes, at some point I will want to do an integration test, but in this case
the real functionality of the class this lives in that I want to test is the
merging of several feeds into one such that the ordering of the resulting
feed items is what I expect. I suppose my issue is one of violating SoC
since my RssAggregator is trying to both fetch individual feeds as well as
merge the results - splitting those responsibilities might let me test the
latter even if the former requires an integration test to properly test.



Steve



--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org



From: altdotnet-***@public.gmane.org [mailto:altdotnet-***@public.gmane.org] On Behalf
Of Jeff Brown
Sent: Thursday, May 15, 2008 2:33 AM
To: altdotnet-***@public.gmane.org
Subject: RE: [altdotnet] Mock XmlReader for Testing? Alternate approaches?



There's no real need to mock the XmlReader or Rss20FeedFormatter themselves.
You should be able to trust that they do what they're supposed to. The
transformation being performed is quite simple and deterministic.



So the main thing I see is that you need to strip out the dependency on that
feed Url so that you can replace it with known static content.



You could of course rip the whole thing out into a service of some sort but
that may be overkill. At best, I'd suggest moving code like this into your
Controller instead of having it in the View. (But it looks like you're
doing ASP.Net.)





Or... you could always write an integration test instead (yet somehow
control what rssfeed.aspx produces). You'll probably want to do that
anyways at some level to make sure the whole thing works when all the pieces
are assembled.



An integration test may be slower and more brittle but it will give you
useful feedback just the same.



Jeff.



_____

From: altdotnet-***@public.gmane.org [mailto:altdotnet-***@public.gmane.org] On Behalf
Of Steven Smith
Sent: Wednesday, May 14, 2008 9:20 PM
To: altdotnet-***@public.gmane.org
Subject: [altdotnet] Mock XmlReader for Testing? Alternate approaches?

I'm struggling to figure out how to test some code that relies on XmlReader
and RssFormatter. Here's the code, which is close to what I'm using in my
library:



XmlReader reader = XmlReader.Create

("http://localhost/MyWebSite/rssfeed.aspx");

Rss20FeedFormatter formatter =

new Rss20FeedFormatter();

formatter.ReadFrom(reader);

reader.Close();

Label3.Text = formatter.Feed.Title.Text;

Label5.Text = formatter.Feed.Copyright.Text;

DataList1.DataSource =

formatter.Feed.Items.Single().lin;

DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx



Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having *those* implement
interfaces which I can then use with mocks but that is a lot of trouble to
go through and I'm really hoping someone will tell me there is a better way.



Thoughts?



Steve





--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org
Roy Osherove
2008-05-15 14:57:46 UTC
Permalink
that sounds like a good candidate for a (at least partial) integration test.
I'd have hard coded input RSS feeds in the project under some directory and
have a test that makes sure that given them as input they are comparable to
an "Expectedoutput.xml" file.
Post by Steven Smith
Yes, at some point I will want to do an integration test, but in this
case the real functionality of the class this lives in that I want to test
is the merging of several feeds into one such that the ordering of the
resulting feed items is what I expect. I suppose my issue is one of
violating SoC since my RssAggregator is trying to both fetch individual
feeds as well as merge the results – splitting those responsibilities might
let me test the latter even if the former requires an integration test to
properly test.
Steve
--
Steven A Smith | ASP.NET MVP | Microsoft Regional Director
President, ASPAlliance LLC | http://aspalliance.com
Behalf Of *Jeff Brown
*Sent:* Thursday, May 15, 2008 2:33 AM
*Subject:* RE: [altdotnet] Mock XmlReader for Testing? Alternate
approaches?
There's no real need to mock the XmlReader or Rss20FeedFormatter
themselves. You should be able to trust that they do what they're supposed
to. The transformation being performed is quite simple and deterministic.
So the main thing I see is that you need to strip out the dependency on
that feed Url so that you can replace it with known static content.
You could of course rip the whole thing out into a service of some sort but
that may be overkill. At best, I'd suggest moving code like this into your
Controller instead of having it in the View. (But it looks like you're
doing ASP.Net.)
Or... you could always write an integration test instead (yet somehow
control what rssfeed.aspx produces). You'll probably want to do that
anyways at some level to make sure the whole thing works when all the pieces
are assembled.
An integration test may be slower and more brittle but it will give you
useful feedback just the same.
Jeff.
------------------------------
Behalf Of *Steven Smith
*Sent:* Wednesday, May 14, 2008 9:20 PM
*Subject:* [altdotnet] Mock XmlReader for Testing? Alternate approaches?
I'm struggling to figure out how to test some code that relies on XmlReader
and RssFormatter. Here's the code, which is close to what I'm using in my
XmlReader reader = XmlReader.Create
("http://localhost/MyWebSite/rssfeed.aspx");
Rss20FeedFormatter formatter =
new Rss20FeedFormatter();
formatter.ReadFrom(reader);
reader.Close();
Label3.Text = formatter.Feed.Title.Text;
Label5.Text = formatter.Feed.Copyright.Text;
DataList1.DataSource =
formatter.Feed.Items.Single().lin;
DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx
Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having **those**
implement interfaces which I can then use with mocks but that is a lot of
trouble to go through and I'm really hoping someone will tell me there is a
better way.
Thoughts?
Steve
--
Steven A Smith | ASP.NET MVP | Microsoft Regional Director
President, ASPAlliance LLC | http://aspalliance.com
--
Thanks,

Roy Osherove
www.TypeMock.com - Simplify Unit Testing

Author of "The Art Of Unit Testing" ( http://ArtOfUnitTesting.com )
www.ISerializable.com (blog)
Jeff Brown
2008-05-15 18:18:28 UTC
Permalink
Ah.
You could extract the RssFeedFetcher from your RssAggregator and test each
one separately. The separation of concerns here will probably benefit you
down the road since both feed fetching and aggregation can become
arbitrarily complex over time as you find more weird exceptional cases to
deal with.

Jeff.

_____

From: altdotnet-***@public.gmane.org [mailto:altdotnet-***@public.gmane.org] On Behalf
Of Steven Smith
Sent: Thursday, May 15, 2008 6:19 AM
To: altdotnet-***@public.gmane.org
Subject: RE: [altdotnet] Mock XmlReader for Testing? Alternate approaches?



Yes, at some point I will want to do an integration test, but in this case
the real functionality of the class this lives in that I want to test is the
merging of several feeds into one such that the ordering of the resulting
feed items is what I expect. I suppose my issue is one of violating SoC
since my RssAggregator is trying to both fetch individual feeds as well as
merge the results - splitting those responsibilities might let me test the
latter even if the former requires an integration test to properly test.



Steve



--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org



From: altdotnet-***@public.gmane.org [mailto:altdotnet-***@public.gmane.org] On Behalf
Of Jeff Brown
Sent: Thursday, May 15, 2008 2:33 AM
To: altdotnet-***@public.gmane.org
Subject: RE: [altdotnet] Mock XmlReader for Testing? Alternate approaches?



There's no real need to mock the XmlReader or Rss20FeedFormatter themselves.
You should be able to trust that they do what they're supposed to. The
transformation being performed is quite simple and deterministic.



So the main thing I see is that you need to strip out the dependency on that
feed Url so that you can replace it with known static content.



You could of course rip the whole thing out into a service of some sort but
that may be overkill. At best, I'd suggest moving code like this into your
Controller instead of having it in the View. (But it looks like you're
doing ASP.Net.)





Or... you could always write an integration test instead (yet somehow
control what rssfeed.aspx produces). You'll probably want to do that
anyways at some level to make sure the whole thing works when all the pieces
are assembled.



An integration test may be slower and more brittle but it will give you
useful feedback just the same.



Jeff.



_____

From: altdotnet-***@public.gmane.org [mailto:altdotnet-***@public.gmane.org] On Behalf
Of Steven Smith
Sent: Wednesday, May 14, 2008 9:20 PM
To: altdotnet-***@public.gmane.org
Subject: [altdotnet] Mock XmlReader for Testing? Alternate approaches?

I'm struggling to figure out how to test some code that relies on XmlReader
and RssFormatter. Here's the code, which is close to what I'm using in my
library:



XmlReader reader = XmlReader.Create

("http://localhost/MyWebSite/rssfeed.aspx");

Rss20FeedFormatter formatter =

new Rss20FeedFormatter();

formatter.ReadFrom(reader);

reader.Close();

Label3.Text = formatter.Feed.Title.Text;

Label5.Text = formatter.Feed.Copyright.Text;

DataList1.DataSource =

formatter.Feed.Items.Single().lin;

DataList1.DataBind();
http://www.dotnetbips.com/articles/addaf09f-9b6b-45d2-aba8-da11f23aa53e.aspx



Neither XmlReader nor Rss20FeedFormatter implements any interfaces. I'm
considering creating wrapper classes for these and having *those* implement
interfaces which I can then use with mocks but that is a lot of trouble to
go through and I'm really hoping someone will tell me there is a better way.



Thoughts?



Steve





--

Steven A Smith | ASP.NET MVP | Microsoft Regional Director

President, ASPAlliance LLC | http://aspalliance.com

ssmith-i0bCTVip/***@public.gmane.org

Loading...