<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">

<!-- RSS as a "standard" is terrible; use Atom.  -coyled -->
<!-- http://coyled.com/atom.xml -->

  <channel>
    <title>Agile Software Musings</title>
    <link>http://gmoeck.github.com/</link>
    <atom:link href="http://gmoeck.github.com/rss.xml" rel="self" type="application/rss+xml" />
    <description>Agile Sofware Craftsman Blog</description>
    <language>en-us</language>
    <pubDate>Tue, 10 Jul 2012 09:51:03 PDT</pubDate>
    <lastBuildDate>Tue, 10 Jul 2012 09:51:03 PDT</lastBuildDate>

    
    <item>
      <title>My Practicing Ruby Article On Responsibility-Centric VS Data-Centric Design</title>
      <link>http://gmoeck.github.com/2012/07/10/practicing-ruby-article-on-responsibility-and-data-centric-design.html</link>
      <pubDate>Tue, 10 Jul 2012 00:00:00 PDT</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2012/07/10/practicing-ruby-article-on-responsibility-and-data-centric-design</guid>
      <description>&lt;h1&gt;My Practicing Ruby Article on Responsibility-Centric VS Data-Centric Design&lt;/h1&gt;

&lt;p&gt;For those of you who have been interested in my writings and talks on
mock objects, I'd highly recommend reading my article that was published
today on responsibility-centric vs data-centric design. This distinction
is at the root of what most people don't understand about mock objects.&lt;/p&gt;

&lt;p&gt;Even if your not subscribed, you can still view the article &lt;a href=&quot;http://bit.ly/Mg0IW0&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Don't Make Your Code &quot;More Testable&quot;</title>
      <link>http://gmoeck.github.com/2012/07/09/dont-make-your-code-more-testable.html</link>
      <pubDate>Mon, 09 Jul 2012 00:00:00 PDT</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2012/07/09/dont-make-your-code-more-testable</guid>
      <description>&lt;h1&gt;Don't make your code &quot;More Testable&quot;&lt;/h1&gt;

&lt;p&gt;In some ways I'm very excited that the Ruby community seems to have
taken up the &quot;Mocking/OO flag&quot; so to speak lately. Most of the Ruby
conferences seem to have talks around &quot;Object Oriented Rails&quot;,
&quot;Isolated Unit Tests&quot;, and things like the &quot;SOLID Design Principles&quot;. And even
more exciting for me is that I see more and more people referencing the
&lt;em&gt;Growing Object Oriented Software Guided By Tests&lt;/em&gt; book. I think these
are all great steps for us towards producing more maintainable software
over time.&lt;/p&gt;

&lt;p&gt;That being said, I don't think we've quite understood all of the value
of the techniques that we're all excited about. We've become focused
on our making things &quot;testable&quot; rather than using our tests to learn
about our design. So I want to try and take the opportunity to propose a
slight course correction within the way that the community has been
talking about these principles, and particularly the way that I perceive the
rest of the community receiving them.&lt;/p&gt;

&lt;h2&gt;Example Conversation&lt;/h2&gt;

&lt;p&gt;I've heard the following conversation happen over and over in various forms
lately:&lt;/p&gt;

&lt;p&gt;&quot;Excited OO Enginner&quot; has been trying out some of these new &quot;OO&quot; ideas that have
been such a buzz in the community on his latest Rails project. He has
been creating POROs for all the services that his controllers might want
to access, and he's been writing isolated unit tests for each of these
components. He's worked hard on the project, and he's particularly proud
of how &lt;strong&gt;fast&lt;/strong&gt; all of his tests run. All of his previous Rails projects
test suites took minutes, or sometimes even hours to run, but all of the
tests for this project run in under a second.&lt;/p&gt;

&lt;p&gt;Then &quot;Experienced Rails Engineer&quot; joins the team, excited to see how the entire
company could learn from this project, particularly its fast test suite. However
as he begins to look at the code, his gut tells him something is
wrong. What would previously have been 10-15 lines of code seems to now
take 20-30. Everywhere he looks, it seems like objects are creating
objects, and he's not even sure why. To make matters worse, in order to
understand the flow though the system he needs to read 5 different files rather
than just one controller file. Unsure of why all this was necessary, he goes to
talk to &quot;Excited OO Engineer&quot;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experienced Rails Engineer&lt;/strong&gt;: &quot;Hey, I have a couple of questions about some of
the code on the new project, you got a sec?&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excited OO Engineer&lt;/strong&gt;: &quot;Sure, whats up?&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experienced Rails Engineer&lt;/strong&gt;: &quot;Well, as I was reading through the code, it seemed
like there was a lot of additional abstractions that didn't seem necessary to
me, and I'd like to understand why we need them.&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excited OO Engineer&lt;/strong&gt;: &quot;I'm not sure what you mean. Where do you feel like we've
over abstracted?&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experienced Rails Engineer&lt;/strong&gt;: &quot;Like for example, lets take a look at this
PostCommentClass:&quot;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PostComment&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@entry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@attributes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;post&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign_attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@entry&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save!&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;LanguageDetector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_language&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;SpamChecker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check_spam&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;CommentMailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_mail&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;post_to_twitter&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;share_on_twitter?&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;post_to_facebook&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;share_on_facebook?&lt;/span&gt;

    &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;post_to_twitter&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;PostToTwitter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;post_to_facebook&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;PostToFacebook&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Experienced Rails Engineer&lt;/strong&gt;: &quot;I could see the necessity of a PostComment object
if we were going to need to share or reuse the code, but for now it
seems like this could just be put into a controller directly. Why do we need
the notion of a PostComment?&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excited OO Engineer&lt;/strong&gt;: &quot;Oh, well you see we need that to be able to test the
code in isolation from other objects. Doing it this way makes it much easier,
and faster to test.&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experienced Rails Engineer&lt;/strong&gt;: &quot;Ok, well I can kind of see the benefit of that,
but some of this seems really confusing to me. Like why does the PostComment
take a user, an entry and attributes into its constructor?&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excited OO Engineer&lt;/strong&gt;: &quot;That's because we want to be able to replace the user,
entry and attributes in our tests with fake objects, so that we can
control the flow through the system here.&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experienced Rails Engineer&lt;/strong&gt;: &quot;And the same would be true of the language
detector taking a comment? It doesn't make sense to me that something
connected to detecting language would need to know the structure of a
comment.&quot;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excited OO Engineer&lt;/strong&gt;: &quot;Well you see we want to assert that the comment is
told to set itself to have the proper language, and so that actually is
the responsibility of the language detector. And since we don't want to
have to use a real comment within our tests, we need to pass it into the
constructor.&quot;&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;The conversation goes on for 15 or 20 minutes. Every time the
&quot;Experienced Rails Engineer&quot; asks a question about what he feels is a
flaw in the design of the code &quot;Excited OO Engineer&quot; explains that it is
necessary to do things that way in order to write fast, isolated tests.&lt;/p&gt;

&lt;p&gt;After the discussion, &quot;Experienced Rails Engineer&quot; concludes that in
order to write an application with fast tests he has to sacrifice his
design, and write 2x as many lines of code. Being the principled
architect that he is, he's not willing to make that compromise. So
he resigns himself to having a slow test suite, so long as he can
continue to write simple, easy to understand code.&lt;/p&gt;

&lt;h2&gt;So what's wrong here?&lt;/h2&gt;

&lt;p&gt;Although I'm quite happy that some of these discussions are actually
happening inside the community, I think that the flavor is somewhat
wrong. The goal of &quot;fast tests&quot; has become an end upon itself, and
people are at risk of destroying their abstractions for the sake of
&quot;testability&quot;.&lt;/p&gt;

&lt;p&gt;When we encounter a bit of code that is hard to test-assuming we're
letting our tests guide the design of the production code we're going to
write-we're going to have one of two responses. We're either going to
say, &quot;how can I write this in a testable way&quot;, or &quot;what about the design
of the system is this test complaining about&quot;.&lt;/p&gt;

&lt;p&gt;The difference between the two is neuanced, and difficult to grasp when
you first start to think this way. With the first approach my primary
concern is solving the problem of something being difficult to test.
With the second approach my goal is to reevaluate the design of my
system in light of the flaw that my test is presenting to me. The end
goal of the second approach is &lt;em&gt;the improving of the design of the
system&lt;/em&gt;, whereas the goal of the first approach is &lt;em&gt;the improving of the
design of the test suite&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Another way to think about this is to ask what is the connection between
testability and good design. A good design is &lt;em&gt;necessarily&lt;/em&gt; easily
testable, but does that mean that any design that is &quot;testable&quot; is
&lt;em&gt;necessarily&lt;/em&gt; good? I don't think that it is.&lt;/p&gt;

&lt;p&gt;A good design is measured in things like coupling, cohesion, and how well the
system hides its complexity. Because of their nature, things with high
cohesion and low coupling are almost always very easy to test. As such, when
something is not easy to test, most of the time one can conclude that
the code does not have high cohesion and low coupling. However unit tests
have no hope of telling us if we're doing a good job hiding complexity
behind our APIs, or modeling our domain in an understandable way. Since
by their very nature they should be isolated, they're unable to serve
that function.&lt;/p&gt;

&lt;p&gt;As such, when our tests start talking to us, I think we want to listen not
so that we can learn how to test them better, but so that we can learn
about the flaws in our design, and perhaps even our domain knowledge.
They're likely telling us that we're missing something in the way that
we're modeling the problem, and begging us to rethink our approach.&lt;/p&gt;

&lt;h2&gt;A Concrete Example&lt;/h2&gt;

&lt;p&gt;So let's get concrete, and look at the particular problem of slow tests. When
our test suites get slow, why are they slow, and what can we learn from
that? In my experience the problem is likely one of two things. First, we might
be needing to instantiate too much of our application in order to get it under
test (and hence the whole thing is coupled together). Or second we're likely
explicitly dependent on some external bit of code that is notoriously slow,
for instance the database in a Rails application.&lt;/p&gt;

&lt;p&gt;In the case of the former, we want to try and separate the concerns of
the application around the lines of the domain. There are likely
concepts that are hidden that are needing to be expressed, named, and
modeled. Unless we do this separation we're not going to be able to learn
about &lt;em&gt;what&lt;/em&gt; is hidden within the &lt;em&gt;how&lt;/em&gt;. Once we discover what these
concepts in isolation from the other parts of the system, it should be
easy to model them in a decoupled, and hence testable way.&lt;/p&gt;

&lt;p&gt;In the case of the latter, we're not separating out the concerns of
the domain from whatever the concerns of the third party software is.
This means that we're needing to test that domain logic through the
third party API. What's wrong with this? Well, again a part of our
domain is hiding within this subsystem, coupled to this third party API,
hiding the &lt;em&gt;what&lt;/em&gt; amidst the &lt;em&gt;how&lt;/em&gt;. Just as in the case above, we want
to extract that domain logic, properly name it, and hide &lt;em&gt;how&lt;/em&gt; it does
what it does behind the &lt;em&gt;what&lt;/em&gt; of a clean API.&lt;/p&gt;

&lt;h1&gt;And so what now?&lt;/h1&gt;

&lt;p&gt;And so I want to encourage us within the Ruby community to make this
slight course correction in the way we think about our isolated unit
tests. Let's never have someone walk away from our code bases thinking
that writing fast tests requires introducing abstractions specificallly
for testing purposes. Instead, let's listen to our tests as a means of
improving our domain models, and hiding the complexity of our systems
behind them. Don't be satisfied with your designs just because they're
&quot;more testable&quot;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Stubbing Is Not Enough</title>
      <link>http://gmoeck.github.com/2011/10/26/stubbing-is-not-enough.html</link>
      <pubDate>Wed, 26 Oct 2011 00:00:00 PDT</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2011/10/26/stubbing-is-not-enough</guid>
      <description>&lt;h1&gt;Stubbing Is Not Enough&lt;/h1&gt;

&lt;p&gt;There has been a good amount of buzz within the Rails community lately
about &quot;Isolation Testing&quot;, &quot;Mock Objects&quot;, and &quot;Fast Tests&quot;. I think
that this is a wonderful trend. Particularly becuase of Corey Haines'
emphasis that practicing Test-&lt;strong&gt;Driven&lt;/strong&gt; development means that you need
to listen to your tests in such a way that pain causes you to change
your &lt;em&gt;design&lt;/em&gt; rather than your &lt;em&gt;tests&lt;/em&gt;. It has been a long time coming
that Rails developers would begin to listen to the pain coming from
their tests, start to use test doubles, and start breaking dependencies
within their design.This is wonderful, and I applaud the effort.&lt;/p&gt;

&lt;p&gt;Yet at the same time, there are a number of ways in which the community
can still press listening to their tests further. For example, although
&quot;mock objects&quot; have become almost a buzz word recently within the community, the
actual objects that are being created by and large are stubs, not mocks. This means
that although we're isolating our tests so that they run faster, we're
not completely dealing with the underlying coupling that is pulling in
all these dependencies, and making our tests slow.&lt;/p&gt;

&lt;p&gt;This post is my attempt to lay out how I think we can both improve the
speed of our tests, while at the same time improving the quality of our
architectures.&lt;/p&gt;

&lt;h2&gt;Mocks Are Not Stubs, And Stubs Are Not Mocks&lt;/h2&gt;

&lt;p&gt;The first clarification that I think is necessary within the community
is that there is a difference between &quot;mocks&quot;, and &quot;stubs&quot;. Although
they both replace a real object within a test, they do different things.
Gerard Meszaros' definition within his book &lt;em&gt;xUnit Test Patterns&lt;/em&gt; is
helpful here:&lt;/p&gt;

&lt;p&gt;&quot;A &lt;strong&gt;Test Stub&lt;/strong&gt; is an object that replaces a real component on which the
SUT [system under test] depends so that the test can control the
indirect inputs of the SUT. It allows the test to force the SUT down
paths it might not otherwise exercise...&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Mock Object&lt;/strong&gt; is an object that replaces a real component on which the
SUT depends so that the test can verify its indirect outputs.&quot;&lt;/p&gt;

&lt;p&gt;The key difference is in the way you use the fake object you create.&lt;/p&gt;

&lt;p&gt;You would use a stub when a method depends on another object for data in the
form of a query. Instead of having to setup a real collaborating object
(which might include hitting the database, etc), you replace that object
with another object that only returns the data that you need, so that
you can avoid having to do the setup. By doing this, you isolate
the object under test, because the only dependency that the test needs
to run is the code for the object itself.&lt;/p&gt;

&lt;p&gt;This is what Corey Haines essentially does in his &lt;a href=&quot;http://confreaks.net/videos/641-gogaruco2011-fast-rails-tests&quot;&gt;&quot;Fast Rails Tests&quot;&lt;/a&gt;
talk. First instead of having a method directly inside of his
ActiveRecord object, he moves it into a module, that looks like the
following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShoppingCart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ShoppingCartExtensions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CalculatesTotalPrice&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;has_many&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:shopping_cart_products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:destroy&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;has_many&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:through&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:shopping_cart_products&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ShoppingCartExtensions&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;CalculatesTotalPrice&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;total_price&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Then in order to test the object in isolation he includes that mixin in
a dummy object inside of his tests like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DummyCartWithProducts&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ShoppingCartExtensions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CalculatesTotalPrice&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Calculating Total Price&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;returns the total price of the products&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DummyCartWithProducts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total_price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Essentially what he's done is treated the ActiveRecord part of the
shopping cart as a collaborator, and created a stub method for its
products. This way he doesn't have to add products into the database
and then read them out just in order to be able to test that the cart
can properly calculate its total price. And as you might have already
guessed, the benefit that comes from the stubs is speed.&lt;/p&gt;

&lt;h2&gt;Why Stubs Are Not Enough&lt;/h2&gt;

&lt;p&gt;The primary problem that people generally point out in relation to this
form of stubbing however is that it leaves you with &quot;brittle tests&quot;
which will give you either false positives, or false negatives. So for
example (and I know this is a bit contrived, but the total price method
is fairly simple) imagine that I changed price to be a money object that
returned the currency type, and the value. What would happen to the
calculating total price method? Well, since the test for the total price
method doesn't use a real product object the test is going to stay
green even though when it is used in production it is going to explode.
These sorts of examples can also go the other way as well- although I
can't think of a way to do this for the shopping cart example - where
the tests break in a refactoring, even though the actual behavior of the
system hasn't changed.&lt;/p&gt;

&lt;p&gt;One might initially think that this whole &quot;fast tests&quot; thing isn't worth
it if it means that our tests are going to become brittle. However the
right response is to go back to how Corey starts his presentation, by
noticing the difference between Test-&lt;strong&gt;Driven&lt;/strong&gt; Development, and
Test-&lt;strong&gt;First&lt;/strong&gt; Development. Practicing Test-&lt;strong&gt;Driven&lt;/strong&gt; development means that you need
to listen to your tests in such a way that pain causes you to change
your &lt;em&gt;&lt;em&gt;design&lt;/em&gt;&lt;/em&gt; rather than your &lt;em&gt;tests&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So what is wrong with the design of a system that requires stubs in
order to test its objects in isolation? That problem is almost always
that the system has poor encapsulation. Why? When you need to stub an
object, it means that your going to be querying some dependency for
information in order to test the behavior of the object. This means that
the behavior of whatever object your testing is &lt;em&gt;necessarily&lt;/em&gt; dependent upon the
behavior of whatever object your stubbing.Now in some cases, maybe this
isn't that bad, but in others this coupling is going to cause a ripple
of changes throughout your system whenever you have to change the object
that needs to be stubbed. This is a flaw in the design, not the tests.&lt;/p&gt;

&lt;h2&gt;How Mocks Solve This Problem&lt;/h2&gt;

&lt;p&gt;The solution to the design problem is to encapsulate our objects so
that their behavior can only be affected through their public API. One
of the primary ways that we can accomplish this is to follow the &lt;a href=&quot;http://pragprog.com/articles/tell-dont-ask&quot;&gt;&quot;Tell,
Don't Ask&quot;&lt;/a&gt; principle. That is, instead of asking an object for its
properties and then making decisions based on that information, we want
our objects to communicate with each other by telling other objects to
do something. Any time something needs to happen that has to operate on
the data outside of the wall of our object, we delegate that to the
object that is responsible for that data to do it for us.&lt;/p&gt;

&lt;p&gt;Another way to think about this is that any objects collaborators should
be playing a different role than the object itself, and each object
should have only a single responsibility. If in the course of developing
our objects we run into another responsibility/role we want to delegate
that task to the object that is playing that role. If you want more
information about how this solves the problem, you should read my
articles, &lt;a href=&quot;http://gmoeck.github.com/2011/09/20/why-you-should-care-about-encapsulation.html&quot;&gt;&quot;Why you should care about encapsulation&quot;&lt;/a&gt;,
and &lt;a href=&quot;http://gmoeck.github.com/2011/09/28/why-you-should-care-about-information-hiding.html&quot;&gt;&quot;Why you should care about information hiding&quot;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This then brings us back to using mock objects instead of stubs inside
of our tests. Remember that Meszaros defined a mock object as an object
that &quot;replaces a real component on which the SUT depends so that the
test can verify its indirect outputs&quot;. What he is saying is that a mock
object stands in for one or more of the roles of an object's
collaborators in order for us to verify the &lt;em&gt;commands&lt;/em&gt; sent to that
object. That is, since some actions do not necessarily modify the state
of the isolated object under test, the way that we want to do our
assertion is if it sends the right command to its collaborator.&lt;/p&gt;

&lt;p&gt;So for example, the following ticket machine interface is an example of
a well encapsulated code:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TicketMachineInterface&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@ticket_reserver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;number_pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;delete_pressed&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chop!&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;submit_request&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@ticket_reserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If I wanted to test this object in isolation, how would I do that? Well,
instead of passing in a real object that would play the role of the
ticket reserver, I could pass in a mock object that would allow me to
assert on the messages that was sent to it. So for example, my test
would look something like the following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TicketMachineInterface&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;reserves the number of tickets inputted when the user submits a request&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ticket_reserver&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_receive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:reserve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TicketMachineInterface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submit_request&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The assertion here is found in the code &quot;ticket_reserver.should_receive(:reserve).with(55)&quot;.
Instead of asserting on the state of the object, I assert on its
behavior. This then allows my test to respect the encapsulation of my
object, and isolate it from its dependencies (which means it runs fast),
while not making my tests brittle.&lt;/p&gt;

&lt;p&gt;The only key becomes mocking roles, instead of objects so that we can
let the object decide &lt;em&gt;how&lt;/em&gt; to accomplish what it is told to do. And
when we follow this &quot;Tell, Don't Ask&quot; style of design it produces
flexable code because it then becomes easy to swap or compose objects
that play the same role in order to change the behavior of the system.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As I said at the outset, I'm quite happy that there seems to be an
increasing interest in Test-&lt;strong&gt;Driven&lt;/strong&gt; Development, and feeling the pain
within our tests. I hope this post has given you something to think
about, and some ways to think about improving the speed of your test
suite without creating brittle tests. I'd love any feedback in the
comments.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Why you should care about information hiding</title>
      <link>http://gmoeck.github.com/2011/09/28/why-you-should-care-about-information-hiding.html</link>
      <pubDate>Wed, 28 Sep 2011 00:00:00 PDT</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2011/09/28/why-you-should-care-about-information-hiding</guid>
      <description>&lt;h1&gt;Why you should care about information hiding&lt;/h1&gt;

&lt;p&gt;As I mentioned in my &lt;a href=&quot;http://gmoeck.github.com/2011/09/20/why-you-should-care-about-encapsulation.html&quot;&gt;last&lt;/a&gt;
post, in preparation for my upcoming RubyConf talk  I'm writing a series of
blog posts about the design priciples that drive the use of mock objects. In
that post I covered what encapsulation is, and why you should care about it.
Today I want to take up a closely related, yet slightly different topic: Information Hiding.&lt;/p&gt;

&lt;h2&gt;What is information hiding?&lt;/h2&gt;

&lt;p&gt;Before talking about why you should care about information hiding, lets
talk a bit about what information hiding is, and what it is not. When I
say that an object hides its information well, I mean that an object hides how it implements its
behavior from the outside world. That is, its API only exposes &lt;em&gt;what&lt;/em&gt; a given
object does, not &lt;em&gt;how&lt;/em&gt; it does it. I've found that people are generally
confused as to the benefits of information hiding because the general
example that is given to illustrate information hiding is something like the following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Encapsulation&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;set_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_value&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@value&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;There are some benefits to doing something like this (you could have
value be computed somehow for instance), but this isn't really
accomplishing information hiding as I described above. It's really
providing an API to modify the data which the object is &quot;encapsulating&quot;.
The object isn't really exposing behavior as much as it is holding
data and as such, in order to use the object, you still have to keep in
mind the low level details of how it works. Any code that
does not hide its information behind a solid API is inherantly a &lt;a href=&quot;http://www.joelonsoftware.com/articles/LeakyAbstractions.html&quot;&gt;leaky
abstraction&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Why should I care?&lt;/h2&gt;

&lt;p&gt;Maybe it's just me, but when my applications get large I find it
difficult to keep all of the details about how everything works in my
head. Even when I'm the one who has written all of the code, it
eventually becomes too much, and it only gets
worse when there are multiple developers working in the same code base.
But when the implementation of &lt;em&gt;how&lt;/em&gt; an object accomplishes what its API
promises to do is hidden, it enables us to treat the object essentially as a black
box. We can trust that the object will do what it is supposed to do,
even if we don't know how it does it.&lt;/p&gt;

&lt;p&gt;The biggest benefit to having good information hiding in my mind is that
it allows you to build abstractions that allow you to work on higher
and higher layers because you can ignore details that are not related to
what your &lt;em&gt;currently&lt;/em&gt; working on. Almost every programmer expects this out of their
libraries, but rarely do they expect it from their own code.&lt;/p&gt;

&lt;p&gt;Consider the following ticket machine interface:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TicketMachineInterface&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@ticket_reserver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;number_pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;delete_pressed&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chop!&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;submit_request&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@ticket_reserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@current_display&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The key thing to notice is that the API exposes behavior instead of
data, or implementation. In order to use the object, you need only to
know its API, and give it a ticket reserver on creation. Notice also,
that the &quot;ticket reserver&quot; is merely a role that another object is going
to play. From the perspective of the ticket machine, all it cares about
is that it implements an api to reserve tickets. It could do that by
communicating over HTTP, writing to a database, or whatever. Since the
ticket reserver seems to have hidden its information as well, the
object is just a role, and any object which implements the role's API
can just step in.&lt;/p&gt;

&lt;h2&gt;Isn't this just encapsulation?&lt;/h2&gt;

&lt;p&gt;You can see that one of the nice side effects of good information hiding
is that it tends to produce well encapsulated code. If your API does not
expose how it does what it does, it is very difficult to change the
behavior of an object without calling its API. However as &lt;a href=&quot;http://nat.truemesh.com/archives/000498.html&quot;&gt;Nat Price&lt;/a&gt;
has pointed out, the two still have different goals, and it can be
helpful to focus on only one of thos goals at a time.&lt;/p&gt;

&lt;h2&gt;What does this have to do with Mock Objects?&lt;/h2&gt;

&lt;p&gt;I think that the above ticket machine interface code is a good example
of encapsulated code that hides its information well. Now if you were
to follow the state based sort of unit testing approach, how would you
write a test for that object? I think the only way you could is to add
getters or setters for the information that your attempting to &quot;hide&quot;.
Whereas with a mock object, you would write a test something like the
following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TicketMachineInterface&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;reserves the number of tickets inputted when the user submits a&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;request&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ticket_reserver&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_receive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:reserve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TicketMachineInterface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ticket_reserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_pressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submit_request&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;If your interested further, I'm going to be giving my RubyConf talk on &lt;a href=&quot;http://rubyconf.org/presentations/21&quot;&gt;&quot;Why You Don't Get Mock
Objects&quot;&lt;/a&gt;, which will focus on
these issues some more. I'll also likely follow up with some more blog
posts after the fact.&lt;/p&gt;

&lt;p&gt;I welcome any feedback you have in the comments.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Why you should care about encapsulation</title>
      <link>http://gmoeck.github.com/2011/09/20/why-you-should-care-about-encapsulation.html</link>
      <pubDate>Tue, 20 Sep 2011 00:00:00 PDT</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2011/09/20/why-you-should-care-about-encapsulation</guid>
      <description>&lt;h1&gt;Why you should care about encapsulation&lt;/h1&gt;

&lt;p&gt;As I've been preparing to give a talk entitled &lt;a href=&quot;http://rubyconf.org/presentations/21&quot;&gt;&quot;Why You Don't Get Mock
Objects&quot;&lt;/a&gt; at this year's RubyConf,
I've begun to change my mind a little bit about why the Ruby community
scorns mock objects. I used to think that the community just didn't
understand how mock objects are meant to be used, but I've come be
believe there is another contributing factor. I think that the reason
the community doesn't really get mock objects is because they don't
really understand the principles that drove the authors of mock objects
to create them to begin with. Things like encapsulation, information
hiding, and the law of demeter are not really well understood, which
makes the motivation behind mock objects very difficult to grasp. As
such, I want to try and sketch out some of these design principles in
some blog posts as a way to &quot;till the soil&quot;, and motivate why someone
would bother to create mock objects in the first place. This is the
first of those blog posts, where I'm going to attempt to lay out the
idea of encapsulation, and why you should care about it.&lt;/p&gt;

&lt;h2&gt;What is encapsulation?&lt;/h2&gt;

&lt;p&gt;Before we talk about why you should care about encapsulation, it would
be good define exactly what I mean by the term. In my experience people often confuse
encapsulation with information hiding, but I think there is a subtle difference
between the two. For the purpose of this blog post, when I say
encapsulation, I mean &quot;the behavior of an object can only be affected
through its API&quot;. Or to put it negatively, an object is not well
encapsulated when its behavior can be affected without calling its
API. Or another way to think about it is that a well encapsulated object draws
a solid boundry or wall around itself, and ensures that all the code that
changes its behavior is contained within the object itself.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TrainTicketStation&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;buy_ticket&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserved?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;TrainIsFull&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserved&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TrainTicketWebsite&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;buy_tickets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_of_seats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserved?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;InsuffecientSeats&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number_of_seats&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;seats_to_reserve&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number_of_seats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;seats_to_reserve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserved&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If we were to have a station and a website both referencing the same
train, then the behavior of both can be affected without touching their public
API. For example, by reserving seats through the website, we can
modify the behavior of the buy_ticket method on the ticket station
object.&lt;/p&gt;

&lt;p&gt;This is because both objects make decisions about reserving seats based upon the
state of their shared train object. And since the state of that train
object is mutable, when one object changes that state, it necessarily
impacts the behavior of the other object.&lt;/p&gt;

&lt;h2&gt;Why should I care?&lt;/h2&gt;

&lt;p&gt;The issue with poorly encapsulated code is that when we go to make a
change, we have to spend a good amount of time tracing what the potential
effects of this change might be on the system as a whole. And the bigger
the system, the bigger this problem becomes. If you have ever worked in a system
where you were afraid to make a change to the behavior of one section of the
code base because you didn't know if that change would break other places,
you've experienced the pain of poorly encapsulated code. To put it in the language
of the definition of encapsulation that I offered earlier, what you were really
worried about that in making this change, you were then changing the behavior
of the system in another place.&lt;/p&gt;

&lt;p&gt;So for example, if we wanted to change the above example from keeping an array
of available seats to just keep a count of the available seats, we would
have to change the code in two places. The buy_ticket method inside of
the train ticket station, and the buy_tickets method inside of the train
ticket website. And if we origionally made the change inside of the
train ticket station, and forgot that the train ticket website was
dependent upon that, then the application would break.&lt;/p&gt;

&lt;p&gt;However when code is well encapsulated, it is like having a wall around
its behavior, and the only things that can modify that behavior are contained
within the wall. With the &quot;wall&quot; of encapsulation in place, we don't
have to worry about if we're changing the behavior of another place in
our system, because we know it is &quot;outside the wall&quot;.&lt;/p&gt;

&lt;p&gt;So for example, imagine that we refactored the origional code to be the following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TrainTicketStation&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;buy_ticket&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buy_tickets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TrainTicketWebsite&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;buy_tickets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_of_seats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buy_tickets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_of_seats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Train&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;buy_tickets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;InsuffecientSeats&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;seats_to_reserve&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;available_seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number_of_seats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;seats_to_reserve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserved&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;available_seats&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@seats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserved?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now, if we wanted to make a change to only keep track of the number of
available seats, instead of using an actual array of seats, the changes are all
located inside of the train object. And we can modify the train, without
having to modify the two ways to purchase tickets as follows:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Train&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@available_seats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seats&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;buy_tickets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;InsuffecientSeats&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@available_seats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@available_seats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;How can we maintain encapsulation?&lt;/h2&gt;

&lt;p&gt;One of the primary ways that one can move towards well encapsulated code
is to follow the &quot;Tell, Don't Ask Principle&quot;, which is what we did in
the code above. Instead of asking an object for its properties and then
making decisions based on that information, objects communicate with
each other by telling other objects to do something. We make it such
that the only properties that can affect the behavior of the object are
contained within the object itself. Any time something needs to happen
that operates on the data &quot;outside our wall&quot;, we tell the object that is
responsible for that data to do it for us. For example in the above example,
instead of asking the train for its seats, and then making decisions
based on what we get back, we merely tell the train to reserve the
proper number of seats, and let it operate on its own data.&lt;/p&gt;

&lt;p&gt;There are of course more design techniques that you can use to help
maintain encapsulation. A couple of them are avoiding global variables
or singletons, copying collections or mutable value objects(entities), and
defining imutable value types. But those are topics for another post.&lt;/p&gt;

&lt;p&gt;For now at least I hope you've come to understand encapuslation a bit
better, and why its a helpful thing to have. I welcome feedback in the
comments.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sproutcore MVC VS Rails MVC</title>
      <link>http://gmoeck.github.com/2011/03/10/sproutcore-mvc-vs-rails-mvc.html</link>
      <pubDate>Thu, 10 Mar 2011 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2011/03/10/sproutcore-mvc-vs-rails-mvc</guid>
      <description>&lt;h1&gt;Sproutcore MVC VS Rails MVC&lt;/h1&gt;

&lt;p&gt;Sproutcore and Rails both use the MVC pattern to organize their code bases, so their architecture must be the same right? Well, not quite. There are actually several differences between the Sproutcore MVC pattern and the Rails MVC pattern that trip people up when they're first starting to work in Sproutcore. This post is my attempt to lay out the two patterns so that their differences can be seen and appreciated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Although I'm using Rails as the example server side pattern, this actually has much more to do with server side MVC VS client side MVC. So just about anything that I say about Rails can be applied to .NET MVC, Django, etc.&lt;/p&gt;

&lt;h2&gt;Rails / Server Side MVC&lt;/h2&gt;

&lt;p&gt;I'm going to assume that most of the people reading this article are already familiar with the basic architecture of a Rails application. The following diagram shows (roughly) how a request goes through the Rails stack.
&lt;img src=&quot;/images/rails_mvc.png&quot; alt=&quot;Rails MVC&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Steps&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The browser sends a request to the web server.&lt;/li&gt;
&lt;li&gt;The web server processes the request, determines which route it belongs to and dispatches that request to the corresponding controller method.&lt;/li&gt;
&lt;li&gt;The controller then asks the model layer for all the necessary information in order to be able to complete the request.&lt;/li&gt;
&lt;li&gt;The model layer collects all the information and returns it to the controller&lt;/li&gt;
&lt;li&gt;The controller gives the appropriate information to the view, and asks it to render&lt;/li&gt;
&lt;li&gt;The view renders itself and gives the rendered html to the controller&lt;/li&gt;
&lt;li&gt;The controller assembles the total page's html and gives it to the web server&lt;/li&gt;
&lt;li&gt;The web server returns the page to the browser&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;So there are a couple of key things to notice in the way that the request comes through the stack.&lt;/p&gt;

&lt;p&gt;First, notice that there is only a single point of entry for the system. All requests are going to come into the system by the browser hitting a route, which the system parses and and does something with. The user might have clicked a button, clicked a link, browsed a certain distance down the page, etc, but the system doesn't know, and it doesn't care. All it knows and cares about is the route which the request comes in with, and then it figures out what to do with it.&lt;/p&gt;

&lt;p&gt;Second, notice that there is only a single point of exit for the system. The system takes the route given, collects all the information that it needs, and generates a big blob of something. It could be HTML, JSON, JavaScript, XML, etc but whatever it is, the system's job is to cobble it together, and give that big blob back to the web server. Whatever the request, the response is going to be a blob of something going back to the browser.&lt;/p&gt;

&lt;p&gt;Rails and other server side frameworks set up their MVC pattern to work this way because they're trying to deal with the fact that HTTP is a stateless protocol. Unlike the traditional MVC pattern developed in Smalltalk, the application itself (particularly the views) can not really have state. Because of this, there is no true rendering involved on the server. It's just going to receive in a request, and dump out some set of data that is going to get rendered by somebody else.&lt;/p&gt;

&lt;p&gt;For most of us who learned MVC from Rails or some other server side framework this &lt;em&gt;is&lt;/em&gt; MVC. It's all that we know. But in reality, this is a simplified version of the traditional MVC framework, and when we're no longer constrained by a stateless protocol we can take full advantage of the full pattern. Which is exactly what Sproutcore does with it's MVC.&lt;/p&gt;

&lt;h2&gt;Sproutcore MVC&lt;/h2&gt;

&lt;p&gt;The Sproutcore MVC framework is close to Martin Fowler's &lt;a href=&quot;http://martinfowler.com/eaaDev/PassiveScreen.html&quot;&gt;Passive View&lt;/a&gt;, but even closer to &lt;a href=&quot;http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html&quot;&gt;Cocoa's&lt;/a&gt; implementation of MVC. Instead of receiving a route, and generating a blob of something, the system responds to events by modifying the state of the system. Let's look at how that is structured:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/sproutcore_mvc.png&quot; alt=&quot;Sproutcore MVC&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Steps&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When the browser raises a user event like a mouse down, the root responder starts up a runloop.&lt;/li&gt;
&lt;li&gt;The root responder gets the view that was the target of the event sends that event to the view, eventually the API for that event on the view view is called.&lt;/li&gt;
&lt;li&gt;That view then processes the event and calls the appropriate action in the controller layer&lt;/li&gt;
&lt;li&gt;The controller layer processes the action, and calls into the model layer do whatever domain action was specified, changing it's state&lt;/li&gt;
&lt;li&gt;The state changes that took place in the model layer are bubbled up into the controller layer through bindings between the model and it's controllers&lt;/li&gt;
&lt;li&gt;The state changes that took place in the controller layer are bubbled up into the view layer through bindings between the controller and the view, and the view re-renders itself&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;Concrete Example&lt;/h3&gt;

&lt;p&gt;In order to make this a bit more concrete, let's look at a specific example as well. Imagine that we're working with some sort of system with a volume control, and let's imagine that the increase volume button is pressed. What would that look like?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In Sproutcore a click is actually a mousedown followed by a mouseup. For simplicity, we're just going to look at the mouseup part, since this is where the actions would really take place.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser receives a mouseup event, and the root responder starts up a runloop. (Sproutcore automatically takes care of this step, you will never even see it)&lt;/li&gt;
&lt;li&gt;The root responder sends the mouseUp message to the IncreaseVolumeButtonView with the event information.&lt;/li&gt;
&lt;li&gt;The IncreaseVolumeButtonView checks it's state to see if it is currently enabled, finds that it is, and so it sends the increaseVolume message it's coordinating controller (this could be a literal controller, or a statechart).&lt;/li&gt;
&lt;li&gt;The volume coordinating controller validates that the state of the larger application allows increasing the volume at this time, finds that it does, and so it sends the model layer the increase volume message.&lt;/li&gt;
&lt;li&gt;The model layer then would change any external system that would need to change to adjust the volume (say a speaker), and change it's representation of that volume (maybe increasing an integer representing the volume by 1).&lt;/li&gt;
&lt;li&gt;At the completion of the changes to the state of the model layer, the bindings for the model layer would fire because a change had taken place, letting the mediating controller know to update itself. (Sproutcore automatically takes care of this step, you only have to setup the initial binding)&lt;/li&gt;
&lt;li&gt;At the completion of the changes to the state of the mediating controller, the bindings for that controller would fire, letting the views that are bound to the volume setting (CurrentVolumeView, and VolumeBarView for example) know to update themselves. (Sproutcore automatically takes care of this step, you only have to setup the initial bindings) The views then would re-render the appropriate part of themselves, ensuring that the display matches the state of the system.&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Notice that the entire system now has state. In the typical server MVC like Rails, the only state that is maintained is in the model layer, and that's through a persistence store like MySQL. This is necessary on the server because you have to rebuild the entire system with each request, but on the client it isn't. Everything is generally kept in memory, and you only have to interact with a persistence store when you can't keep everything in RAM, or when you want to save the system's state.&lt;/p&gt;

&lt;p&gt;Also, since you don't have to rebuild the entire system with each request, each layer has a current state in memory, and the job of the system is to propagate the appropriate changes given the action of the user. This allows us to build richer UIs that respond differently when they are in different states much more easily. As such, the system's job is no longer primarily about generating output, maintaining and updating it's state.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;When I first started working on the client side the only MVC that I knew was the one from Rails, and I didn't even know that I needed to change the way that I think about MVC in order to get how something like Sproutcore functioned. Hopefully this post has at least pointed you in the right direction. If your looking for more information, I would recommend reading through &lt;a href=&quot;http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html&quot;&gt;Cocoa's&lt;/a&gt; documentation on it's design patterns (particularly the MVC section), and then look through some larger Sproutcore apps like &lt;a href=&quot;http://github.com/suvajitgupta/Tasks&quot;&gt;Tasks&lt;/a&gt;, or &lt;a href=&quot;http://github.com/erichocean/otherinbox&quot;&gt;OtherInbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although some have attempted to bring the server side model of MVC into the client (Backbone.js's controllers for example &quot;provide methods for routing client-side URL fragments, and connecting them to actions and events&quot;), in the long term I think we will be better served if we learn to use the client MVC pattern for our client side apps, and the server MVC pattern for our server apps. It certainly can take some getting used to, but since we have state on our clients I think we should take advantage of it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Testing Your Sproutcore Views</title>
      <link>http://gmoeck.github.com/2011/02/25/testing-your-sproutcore-views.html</link>
      <pubDate>Fri, 25 Feb 2011 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2011/02/25/testing-your-sproutcore-views</guid>
      <description>&lt;h1&gt;(Unit) Testing Your Sproutcore Views&lt;/h1&gt;

&lt;p&gt;About a week ago there was an &lt;a href=&quot;https://github.com/sproutcore/sproutcore/issues#issue/191&quot;&gt;issue&lt;/a&gt; created on the sproutcore repository asking about how to programmatically trigger events for unit testing purposes. This created an interesting discussion between Michael Cohen (&lt;a href=&quot;http://frozencanuck.wordpress.com/&quot;&gt;frozencanuck&lt;/a&gt;) and myself about what is the best way to unit test a Sproutcore view. I figured that this would be a good topic for a blog post, both from the testing perspective and from the Sproutcore perspective. So lets first take a closer look at what our discussion was about.&lt;/p&gt;

&lt;h2&gt;The common way of testing views&lt;/h2&gt;

&lt;p&gt;The approach with Mike articulated seems to be the standard way by which views are tested using sproutcore. Basically what he suggested is that you create and render the view which you want to put under test, and then interact with and assert on html for the view. To understand this better, let's look at an example from Mike's excellent &lt;a href=&quot;http://frozencanuck.wordpress.com/2010/04/06/simulating-events-in-sproutcore/&quot;&gt;blog post&lt;/a&gt; on simulating events in sproutcore where he is testing a segmented view like the one bellow.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/segmented_view.png&quot; alt=&quot;Segmented View&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;SC.SegmentedView Logic&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RunLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MainPane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;childViews&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SegmentedView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RunLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;childViews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;teardown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Check that second item is selected correctly&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.sc-segment&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mousedown&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.sc-segment&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mouseup&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;the second item should be selected&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Ok, so what is going on here? We're trying to verify that when the second item within the view (the bar section in the picture above) is clicked that it is now the selected item. In order to do this, Mike sets up his view to be nested in a main pane, and renders that pain to the page using the append method of his setup. Then, within his unit test he finds the &quot;bar&quot; section of the page (by knowing that it is the second view with the se-segment class), and triggers a mouse down, followed by a mouse up (since that is the equivalent of a click event in sproutcore). He then asserts the the value for the segmented view is equal to bar, which lets him know that the second section is selected.&lt;/p&gt;

&lt;h2&gt;So what is wrong with this?&lt;/h2&gt;

&lt;p&gt;The first thing that I think needs to be pointed out is that this is not a unit test for the SegmentedView class. The system under test here spans a much larger range than just the SegmentedView code. The fact that we are needing to add other classes in our test setup is the first smell that should indicate this. But let's ignore that for just a moment, and look at what happens in the action which we're testing.&lt;/p&gt;

&lt;p&gt;The first thing that we do is we do is ask the DOM for the element which we want to click. Then we send a message to the singleton SC.Event to trigger a &quot;mousedown&quot; event on that dom object - this much should be clear to the code. What happens next though isn't clear from the code. Roughly what happens is the following. SC.Event triggers the event on the DOM node, which is then picked up by the RootResponder. The RootResponder figures out how to pass the message into the system, does so, and eventually the segmented view receives a mouseUp message with the event passed in. The segmented view then handles this message (doing something). This process is illustrated bellow:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/view_events.png&quot; alt=&quot;View Events&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The same thing then happens with triggering the mouseup event. And then finally, we assert that the value of the view is 'bar'.&lt;/p&gt;

&lt;p&gt;The key thing to notice is that even in this abbreviated sequence how many pieces of sproutcore are we touching? A lot! Instead of isolating our view class to do assertions on it alone, we're using the bigger portion of the stack to &quot;unit&quot; test our view. As such, this isn't really a unit test but an integration/functional test.&lt;/p&gt;

&lt;p&gt;So then how would i test this?&lt;/p&gt;

&lt;h2&gt;My way of testing views (Using mocks and stubs for isolation)&lt;/h2&gt;

&lt;p&gt;What I want to test within the unit test for my view is that it's api functions properly. As such, when I'm testing my view, I don't want to think about DOM events at all, but calls into my api. Some might be confused by this idea, so perhaps it might first be best to ask ourselves what is a view class really?&lt;/p&gt;

&lt;p&gt;I think most may think of a Sproutcore view as how their users are going to view the state of their application, but this isn't quite correct. According to the documentation, views provides two functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They translate state and events into drawing instructions for the web browser.&lt;/li&gt;
&lt;li&gt;They act as first responders for incoming keyboard, mouse, and touch events.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Really though views doesn't even really talk to the web browser or the DOM directly. They collaborate with a render context, which at some later point in time will be used by the run loop to talk to the DOM directly. This means that I can be assured that the view itself is doing the right thing without ever having to interact with the DOM at all, because the view itself doesn't interact with the DOM. All I need to verify is that the view properly changes it's own state and that it sends the correct message to it's collaborators. Then is it's collaborator's job to do the right thing with that message, not the view itself.&lt;/p&gt;

&lt;p&gt;Since the segmented view is a complicated example and I think most people aren't necessarily familiar with the ideas I'm describing, I'm going to give an example with a little simpler situation. Let's take just take a look at a standard button view. The first thing that I would like to happen is when the user mouses over the button, it changes color and when it mouses away, it changes back.&lt;/p&gt;

&lt;p&gt;How would I test this? First I would write a failing integration test (more on that at the end of this post), but then what? Well I want to define the interface to my view such when the mouse enters it, it knows it is being hovered over. So I could write something like the following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;MyApp.MyButtonView#mouseEntered&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyButtonView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;When the mouse is hovering over the button&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mouseEntered&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;isHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Then the button knows the mouse is hovering over it&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;But that doesn't deal with any of the HTML your thinking. That's right, because here we're only dealing with the view as a responder, not as a translator- and yes, we could (should?) break this into two classes each having a single responsibility. The mouseEntered function shouldn't handle the translation into HTML, the render method does. Lets say that html translation of the button being hovered over is to say that the button adds the class 'mouseHovering'. These could be my unit tests:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addedClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;MyApp.MyButtonView#render&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyButtonView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addedClass&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;When the mouse is hovering over the view&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;isHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;addedClass&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;none&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addedClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mouseHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Then the button has the class mouseHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;When the mouse is not hovering over the view&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;isHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;addedClass&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;none&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addedClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;none&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Then the button does not have the class mouseHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;So what I've done here, is I have created a mock object to stand in the place of the render context, but note it is &lt;em&gt;not&lt;/em&gt; a render context. This is because I'm mocking the role that the render context plays here, not a render context itself. All I'm doing is defining an API for the role that the render collaborator of the view will use. Then I'm essentially just checking that the proper message is sent to the render collaborator, and trusting that it does it's job right when it receives that message(if I were BDDing this, my integration test would still be failing, so those would be the next tests I wrote).By doing this, I've isolated the view from all of the other components of the system, and I'm checking only that the view is functioning correctly.&lt;/p&gt;

&lt;p&gt;If instead of using QUnit, I were to use Jasmine, it's spy framework makes doing this even easier, and in my opinion cleaner:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;MyApp.MyButtonView&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#render&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addClassSpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyButtonView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}};&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;addClassSpy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;spyOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;addClass&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;when the mouse is hovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;isHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

      &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;the button has the class mouseHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClassSpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;mouseHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;when the mouse is not hovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;isHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

      &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;the button does not have the class mouseHovering&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClassSpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;not&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Perhaps it would be helpful if I were to give one more example to show the power of this approach. Let's say that we're ready to test that on a mouse up, the action for our button is called. For simplicity, let's not make that action dynamic. How would I test that? Like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;MyApp.MyButtonView&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#mouseUp&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;delegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;buttonClickedSpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyButtonView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buttonClicked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;buttonDelegate&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;delegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;buttonClickedSpy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;spyOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;delegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;buttonClicked&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;with valid conditions for click to happen&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;announces that it was clicked&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buttonClickedSpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Here you can see that it doesn't really even matter what type of class the button is delegating to, all that matters is that it's interface contains the method buttonClicked. This delegate could be a statechart, a responder, a controller, or whatever and the test doesn't care. More importantly the view doesn't care. And it shouldn't, because all we need to see to know that the view is functioning properly is that it is sending the right object the proper message, not what that object is doing with the message.&lt;/p&gt;

&lt;h2&gt;So then how do you know if your whole system is working?&lt;/h2&gt;

&lt;p&gt;One of the things that Mike brought up in our discussion is that he &quot;wants his tests to fully exercise the event handling logic and do it in a way that closely simulates a real world environment within the confines of unit testing&quot;. The approach that I'm advocating here does push it a bit further away from a &quot;real world environment&quot;, as we're isolating the components for testing purposes. But that is why acceptance/integration tests are so important.&lt;/p&gt;

&lt;p&gt;I do want to verify that the components of my system are working together in a way that provides value to &lt;em&gt;the consumer&lt;/em&gt; of my code. When I don't isolate my components, it is hard for my tests to truly think about the way that a consumer is going to interact with my system, because my test is focusing on some component's function. However when I have successfully isolated my components with unit tests, my acceptance/integration tests can use the system the same way the user would. So here's an example of an acceptance test for the segmented view that we were talking about earlier, using my jasmine-sproutcore library:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Selecting an item from a segmented view&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Given a page that contains a segmented view&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;beforeAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MainPane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;childViews&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SegmentedView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                  &lt;span class=&quot;nx&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                  &lt;span class=&quot;nx&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;})]&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;afterAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;When I am looking at that page&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;beforeAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RunLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RunLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

      &lt;span class=&quot;nx&quot;&gt;afterAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RunLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;pane&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RunLoop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

      &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;And I click on the second item in the segmented view&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;beforeAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;clickOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#barButton&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//You can use whatever CSS selector would be clearest.&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

        &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Then I should see that the second item is selected&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;//sel is how the segmented view marks what is selected&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CoreQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#barButton&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHaveClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;sel&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

        &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;And I should see that the first item is not selected&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CoreQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#fooButton&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;not&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHaveClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;sel&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The main benefits that I see in this is that it is looking at the problem from a more abstract viewpoint. It both manipulates the page as a consumer would, and verifies that the page is working in a way that the consumer would. It doesn't need to care about the implementation details - since those are covered with unit tests - and so it is free to merely verify that the total functionality is working. And it can speak in the language of the consumer, instead of the developer.&lt;/p&gt;

&lt;h2&gt;So why does this discussion matter?&lt;/h2&gt;

&lt;p&gt;When I was first trying to figure out how to test my views, the first thing I did was go look at how the pre-built views are tested. To my dismay a good amount of the pre-built views functionality was not even tested, and even that which was was didn't impress me very much. In fact, the testing as on a whole for the Sproutcore community hasn't really impressed me very much (but I'm pretty spoiled from the Ruby community). This is really rather sad, because Sproutcore makes it &lt;strong&gt;so&lt;/strong&gt; much easier to test your applications than a vanilla javascript application. But hopefully this post has helped you to think through how to better test your views, so that our applications will be more easily changeable and cleanly designed in the future.&lt;/p&gt;

&lt;p&gt;If you have any feedback, I would relish challenges in my thinking :) Please feel free to leave some comments.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Mocking, History &amp; Ruby Community</title>
      <link>http://gmoeck.github.com/2010/12/10/mocks-history-and-ruby.html</link>
      <pubDate>Fri, 10 Dec 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/12/10/mocks-history-and-ruby</guid>
      <description>&lt;h1&gt;Mocking, History &amp;amp; the Ruby Community&lt;/h1&gt;

&lt;p&gt;Recently Nick Gauthier wrote a &lt;a href=&quot;http://www.ngauthier.com/2010/12/everything-that-is-wrong-with-mocking.html&quot;&gt;post&lt;/a&gt; in which he critiqued how a lot of people use mocks in RSpec. Then in the comments on the post there was a good discussion with Nick, David Chelimsky and others discussing the topic. But in the course of reading through, a bigger problem jumped out at me. As a whole, we in the Ruby community are too ignorant of history and theory. So this post is not a critique per se on the mocking discussion but rather an attempt to point out a larger problem.&lt;/p&gt;

&lt;h2&gt;Why does mocking exist?&lt;/h2&gt;

&lt;p&gt;Mocking was first presented (publicly) at the XP 2000 conference by Tim Mackinnon, Steve Freeman and Philip Craig. You can read the original paper &lt;a href=&quot;http://connextra.com/aboutUs/mockobjects.pdf&quot;&gt;here&lt;/a&gt;. It was developed initially as a way to do two things: (1) Test an object in isolation from its dependencies. (2) Avoid polluting domain objects with getters so that the testing framework could check their internals.&lt;/p&gt;

&lt;p&gt;However, as the description of the concept evolved, the idea of mocking objects became much more about OO-design than it was about dependencies. The &quot;founders&quot; clarified their usage in 2004 at OOPSLA in &lt;a href=&quot;http://www.jmock.org/oopsla2004.pdf&quot;&gt;this&lt;/a&gt; paper. They desired to design their systems &quot;as a web of collaborating objects&quot; each of which followed the &lt;a href=&quot;http://www.objectmentor.com/resources/articles/srp.pdf&quot;&gt;SRP&lt;/a&gt;, and &lt;a href=&quot;http://en.wikipedia.org/wiki/Law_of_Demeter&quot;&gt;the Law of Demeter&lt;/a&gt;. As such, they desired to change the behavior of the system by changing the composition of its objects - that is adding and removing instances or pluggin different combinations together - rather than writing procedural code. Therefore, they insisted on &quot;focused objects that send commands to each other and don’t expose any way to query their state&quot;.&lt;/p&gt;

&lt;p&gt;This of course then seemed to back them into a corner, since if their objects did not expose their state, how was one to write unit tests for said objects? They proposed to &quot;change the way we approach TDD&quot; by focusing more on the interaction (or &lt;a href=&quot;http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html&quot;&gt;&quot;messages&quot;&lt;/a&gt; as Alan Kay would call them) between the objects. Instead of testing the state of an object after a given operation, they proposed checking how the object communicates with its neighbors. The unit test's goal then is to make explicit the relationship between the target object and its environment.&lt;/p&gt;

&lt;p&gt;Perhaps the worst decision that they made in the description of their procedure is that they originally decided to call the testing structures mock &quot;objects&quot;. Because of the name of their proposed test structure, people thought that they were advocating designing the &lt;strong&gt;objects&lt;/strong&gt; that the mock is representing. In fact however they were advocating that one ask what &lt;em&gt;role&lt;/em&gt; that object is going to have to play, &lt;em&gt;without&lt;/em&gt; specifying how one is going to implement that role. They were attempting to advocate that one mock an &lt;strong&gt;idea&lt;/strong&gt; or a &lt;strong&gt;role&lt;/strong&gt;, not an implementation, so that the object under testing would be forced to delegate any responsibility that was not their's.&lt;/p&gt;

&lt;h2&gt;So then how should mocks be used?&lt;/h2&gt;

&lt;p&gt;In the section of the RSpec book which Nick quoted, David created a mock object representing an output object which is a dependency for the codebreaker game that they were writing. The ensuing discussion then focused upon the need to specify the implementation of the standard output object, and as such making the code brittle. Nick's objection (and quite rightly) was that David was seeming to specify the implementation of the standard out object in his test.&lt;/p&gt;

&lt;p&gt;In fact though, the real problem is that David has broken the rule of &quot;only mock types you own&quot;. What he should have done (and could easily refactor it to) is created a thin wrapper around the standard output object that speaks in the domain of the system in which he was working (notice by the way that I'm speaking in David's language from his comments, he knows this). The mock output object then would have represented &lt;em&gt;the idea&lt;/em&gt; of an output object within the codebreaker domain, and it would have been acknowledging the fact that the game object should &lt;strong&gt;not&lt;/strong&gt; be responsible for its own output (SRP). The mock object then would be specifying not &lt;strong&gt;how&lt;/strong&gt; the other object functioned, but &lt;strong&gt;what&lt;/strong&gt; it must do. He then would be able to temporarily mock the output object, and once the object specifying the state of the game was green, he could write tests to specify &lt;em&gt;how&lt;/em&gt; that object functions. Also, then the implementation of &lt;em&gt;how&lt;/em&gt; that output object works could change without breaking the game object, and vice versa.&lt;/p&gt;

&lt;h2&gt;So then what can we learn?&lt;/h2&gt;

&lt;p&gt;I think the real thing to take away from this discussion is that we as a community need to do a better job of educating ourselves about why the tools that we use exist, and what they were intended to accomplish. The Ruby community is a great place to work in, and we really are pushing the boundaries on many fronts. However we tend to not care as much about ideas that were thought of and developed in other languages like Java. We tend to only focus on their ruby implementation, instead of understanding the ideas behind the technology. If we are going to be true craftsman, I think we also need to learn our history and theory.&lt;/p&gt;

&lt;p&gt;Also, I think that the true solution to when we see newbies making the sort of errors that newbies make is to point them to the right sources. They need to know the theory behind the tool that they're using. They don't only need to learn how to do something, but why. And history often is an engaging source to get them interested.&lt;/p&gt;

&lt;h2&gt;Further Mocking References&lt;/h2&gt;

&lt;p&gt;Martin Fowler, &lt;a href=&quot;http://martinfowler.com/articles/mocksArentStubs.html&quot;&gt;&quot;Mocks Aren't Stubs&quot;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dan North (Founder of BDD), &lt;a href=&quot;http://blog.dannorth.net/2008/09/14/the-end-of-endotesting/&quot;&gt;&quot;The End of Endotesting?&quot;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;XUnit Test Patterns by Gerard Meszaros &lt;a href=&quot;http://www.amazon.com/dp/0131495054?tag=xuntespat0f-2&amp;amp;camp=14573&amp;amp;creative=327641&amp;amp;linkCode=as1&amp;amp;creativeASIN=0131495054&amp;amp;adid=1WNXJS2GC92A3C5RKSY4&amp;amp;&quot;&gt;Amazon Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Growing Object-Oriented Software, Guided by Tests by Steve Freeman (One of the founders of mocking) &lt;a href=&quot;Growing%20Object-Oriented%20Software,%20Guided%20by%20Tests&quot;&gt;Amazon Link&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Using the Sproutcore Master Branch</title>
      <link>http://gmoeck.github.com/2010/01/31/using-sproutcore-master-branch.html</link>
      <pubDate>Sun, 31 Jan 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/01/31/using-sproutcore-master-branch</guid>
      <description>&lt;h1&gt;Using the Sproutcore Master Branch&lt;/h1&gt;

&lt;p&gt;The question has come up several times in the irc the last few days, as to how to use the Sproutcore master branch. Peter Wagenet keeps answering it, and i figured it would be helpful to write it down.&lt;/p&gt;

&lt;h2&gt;NOTE&lt;/h2&gt;

&lt;p&gt;The following is currently only working on Ruby 1.9.2. The easiest way to set that up is to use &lt;a href=&quot;http://rvm.beginrescueend.com/interpreters/ruby/&quot;&gt;rvm&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First &lt;code&gt;gem install bundler&lt;/code&gt; if you don't have it&lt;/li&gt;
&lt;li&gt;In your project dir make a file called Gemfile&lt;/li&gt;
&lt;li&gt;Put in &lt;code&gt;source 'http://rubygems.org'&lt;/code&gt; and &lt;code&gt;gem 'sproutcore', '1.5.0.pre.3'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;bundle install --binstubs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;mkdir frameworks &amp;amp;&amp;amp; cd frameworks&lt;/li&gt;
&lt;li&gt;git clone git://github.com/sproutcore/sproutcore.git&lt;/li&gt;
&lt;li&gt;Instead of using &lt;code&gt;sc-server&lt;/code&gt; use &lt;code&gt;./bin/sc-server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Windows&lt;/h3&gt;

&lt;p&gt;Windows also needs to add &lt;code&gt;gem 'eventmachine', :git =&amp;gt; 'git://github.com/eventmachine/eventmachine'&lt;/code&gt; because otherwise it won't compile&lt;/p&gt;

&lt;h2&gt;UPDATED 2011-02-22&lt;/h2&gt;
</description>
    </item>
    
    <item>
      <title>BDD in Sproutcore - Corrections for parts 1-3</title>
      <link>http://gmoeck.github.com/2010/01/15/bdd-in-sproutcore-corrections-for-1-3.html</link>
      <pubDate>Fri, 15 Jan 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/01/15/bdd-in-sproutcore-corrections-for-1-3</guid>
      <description>&lt;h1&gt;Corrections for parts 1-3&lt;/h1&gt;

&lt;p&gt;I haven't gotten any feedback from people from my posts thus far, but I've noticed several places where my code should change, and get cleaned up a bit. This is what this post will be about.&lt;/p&gt;

&lt;h2&gt;Using outlets&lt;/h2&gt;

&lt;p&gt;The first really brittle piece of the code that I noticed is where I was using getPath to reach into the view and find elements. By using a long string like 'mainPage.mainPane.middleView.contentView' I'm coupling a good number of my tests to the current structure of my views. In order to fix this, and to give the element a description that is closer to our domain, we can refactor this dependency to use SC.outlet:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/781228.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;What SC.outlet does is generate a computed property that will look up the passed property path the first time you try to get the value. I've done this for the add task button, the count of task, and the list of tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/gmoeck/sc-bdd-todos/commit/8ece0aa3114fbfc9810572e2cf79e6aed597582d&quot;&gt;changes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Testing the wrong part of the application in the integration tests&lt;/h2&gt;

&lt;p&gt;When checking what the list of tasks were in the application I generally would find the view, and then get the content. The problem with this is that I'm then checking the controller, instead of checking the view. However, when I make this change in the viewing_task spec, the view is no longer able to directly find the indexOf the task. Instead, I use the itemViewForContentObject method on the collection view to ensure that the object belongs to it.&lt;/p&gt;

&lt;p&gt;This still doesn't feel quite right to me in an end-to-end sense, since I'm still poking at the view object which is something that the user isn't going to do directly. However going through the HTML is difficult when your using the desktop views provided with Sproutcore. I think the ultimate solution to this for me is going to be moving away from using those views, and into custom views which I get to set the HTML for so I can directly validate based on css or xpath selectors. I haven't really gotten to try this yet though.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/gmoeck/sc-bdd-todos/commit/3f5848c87950b91fbd7e5e108c6c85cec2343c97&quot;&gt;changes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Using get for length&lt;/h2&gt;

&lt;p&gt;Another place that the code that I wrote needs to change is the way that I'm getting the length of todos from the store, and from the list view. One of the standard rules of SC is to use the getters provided by the framework to access the attributes of an object, which I wasn't doing in my tests. In this case, since I was only accessing it in the tests while outside the runloop, I don't think it made any difference in terms of correctness (the tests still passed), but it's still a good practice to do things right, so I've changed it:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/781245.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;&lt;a href=&quot;https://github.com/gmoeck/sc-bdd-todos/commit/13bedc8cd87b16c2ae487a8519aa56533c61d73a&quot;&gt;changes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;If nothing else, these changes should demonstrate that I'm no expert in Sproutcore, and I'm certainly open and looking for feedback on where my mistakes are. I hope this series will be helpul as well for those who are attempting to learn like I am. If you spot something that you think can be done better, or that is unclear please feel free to leave a comment or shoot me an e-mail at gmoeck [at] gmail.com. If we can get a dialog going with those of us using/playing with Sproutcore all of our codebases will improve.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sproutcore training with Erich Ocean- A Review</title>
      <link>http://gmoeck.github.com/2010/01/12/sproutcore-training-with-erich-ocean-a-review.html</link>
      <pubDate>Tue, 12 Jan 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/01/12/sproutcore-training-with-erich-ocean-a-review</guid>
      <description>&lt;h1&gt;Sproutcore training with Erich Ocean: A Review&lt;/h1&gt;

&lt;p&gt;So today I took took the day off work, and attended Erich Ocean's Sproutcore training session that he's been posting on the Sproutcore mailing &lt;a href=&quot;http://groups.google.com/group/sproutcore/browse_thread/thread/18fb7b643a745552#&quot;&gt;list&lt;/a&gt;. I figured that since Erich is the only source that I have seen for training, and since he also is the one who has put forward the &lt;a href=&quot;http://www.google.com/url?sa=D&amp;amp;q=http://erichocean.com/book/index.html&quot;&gt;book proposal&lt;/a&gt; that it would be a good oportunity to improve my skill in the Sproutcore world. This article is an account of my experience. Hopefully it will help you decide whether to attend his next class.&lt;/p&gt;

&lt;h2&gt;Format&lt;/h2&gt;

&lt;p&gt;The class mainly took the form of Erich talking though diagrams or code via screen-sharing, and answering questions inputted into a chat window as we were going along. This was accomplished using GoToMeeting's GoToTraining &lt;a href=&quot;http://www.gotomeeting.com/fec/training/online_training&quot;&gt;software&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This format generally worked quite well. There were 23 people who showed up for the class, so initially I was a little worried that the chat would be too busy. However only 6 or 7 people really actively participated in the chat, so it was easy to get my questions answered. The only downside to the setup was that the audio (and I think the video) kept going out on Erich's side. This happened about ~10 times over the 4 hour period, where it seemed like his network connection just died. Overall though I didn't find it to be terribly painful, and it was a small price to pay in order to be able to get training in my pajamas, and from my own home.&lt;/p&gt;

&lt;p&gt;In our case, because Erich was on the road he wasn't recording our particular session, but he did say that he was going to give us access to a previously recorded session, which had the same content.&lt;/p&gt;

&lt;h2&gt;Content&lt;/h2&gt;

&lt;p&gt;The content was broken down into three sections, which covered the follwing material:&lt;/p&gt;

&lt;h3&gt;Sproutcore MVC&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sproutcore runloop&lt;/li&gt;
&lt;li&gt;How bindings fit into the MVC&lt;/li&gt;
&lt;li&gt;How the MVC is different from something like Rails&lt;/li&gt;
&lt;li&gt;The &quot;V property&quot;, and the order things must process through the stack&lt;/li&gt;
&lt;li&gt;Using pre-built controllers&lt;/li&gt;
&lt;li&gt;&quot;event-check state-action&quot; paradime&lt;/li&gt;
&lt;li&gt;The two fundamental tasks to correctly code an app&lt;/li&gt;
&lt;li&gt;How the cloud slows everything down&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Statecharts&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The statecharts notation&lt;/li&gt;
&lt;li&gt;How to desigin statecharts&lt;/li&gt;
&lt;li&gt;How statecharts solve &quot;the two fundamental tasks to correctly coding an app&quot;&lt;/li&gt;
&lt;li&gt;Practicing building a statechart&lt;/li&gt;
&lt;li&gt;How to &quot;unit&quot; test a statechart&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Miscelanious Topics&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How to divide up the work with statecharts and the mvc&lt;/li&gt;
&lt;li&gt;How to access subviews (SC.Outlet)&lt;/li&gt;
&lt;li&gt;When to use custom views (always)&lt;/li&gt;
&lt;li&gt;How to connect with your backend (by avoiding datasources)&lt;/li&gt;
&lt;li&gt;Q/A&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;The class was billed as a course that would &quot;permanently change how you think about application construction and coding with a unique, visual explanation of the MVC architecture in SproutCore&quot;, and I think for the most part it accomplished it's goals in that regard. Erich clearly was both very knowledgeable about Sproutcore, and very opinionated. He was not merely content to layout the way things are in Sproutcore, but desired to impart to his students how he thought they could improve the structure of their applications. It was this opionated approach that I think was the class's greatest benefit, although it left me with several questions.&lt;/p&gt;

&lt;p&gt;For instance, Erich said that any view that is going to be drawing content should be a custom view, and that one should never extend those views from anything but SC.View. This viewpoint astounded a large number of people in the class, and several people expressed that they felt that their entire application had been built on faulty ideas. When some said that they liked the idea of moving away from html, Erich suggested that they might find Cappuccino to be a better fit than Sproutcore. This was all the more shocking although it certainly necessitated transforming about how one should think about building their view layer.&lt;/p&gt;

&lt;p&gt;This was not the only place that what Erich said seemed to stray from the &quot;suggested way&quot; that I have seen in working through the wiki tutorial. The following are a couple more examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want to move all of your domain logic onto the server if you can, and only store attributes on the client.&lt;/li&gt;
&lt;li&gt;Put no custom code in controllers.&lt;/li&gt;
&lt;li&gt;Have a singleton application controller which controls all the actions of the application.&lt;/li&gt;
&lt;li&gt;.observes is a code smell&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I point these things out not because I disagree with them, but because I'm not sure if I'm qualifed at this point to even have an opinion on these issues. The class certainly challeged me in that regard, but it also left me with a distict feeling that I wasn't getting the &quot;Sproutcore way&quot;, but the Erich Ocean's way. Perhaps this is exactly what I need - only time will tell- but for the time being, it left me with more questions than answers - particularly about how people on the core team view Erich, and his approach.&lt;/p&gt;

&lt;p&gt;Having said that, I certainly felt that I got something from the course. The content was engaging and well prepared, and it was fun to work through the material. The training materials on Sproutcore are definatly lacking, and so to have the oportunity to watch, and talk with Erich for 4 hours was a steal of a deal at double what I was charged. I would certainly recomend the course to others, just go into the class knowing your getting an opinionated lesson.&lt;/p&gt;

&lt;h2&gt;EDIT - 2011-01-29&lt;/h2&gt;

&lt;p&gt;Couple points of clarification:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;There doesn't seem to be as much tension between what Erich was saying in the class and the canonical way of building views. Yehuda clarified this point in a thread on the developers list, which you can read &lt;a href=&quot;http://groups.google.com/group/sproutcore/browse_thread/thread/eb75b3fbc0c69da3&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Erich further clarified to me that he would not always move all of his domain logic onto the server, but only in a case of working on a LAN, when the price of the network is basically zero.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, when I said &quot;singleton application controller&quot;, you can see my naivete in relation to Sproutcore. Erich actually meant a single responder, usually putting the logic in SC.Application for small to medium size apps. Although everything seems to be moving to statecharts now.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Most of the things that shocked me was likely relating to the wiki being so outdated (particularly the todos tutorial). The guides seem to fit into Erich's approach without as much of a problem. Erich's opinionated tone made it seem to me like there was more of a difference than there really was.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      <title>BDD in Sproutcore - Part 3 ~ Adding a task</title>
      <link>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-part-3.html</link>
      <pubDate>Sun, 10 Jan 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-part-3</guid>
      <description>&lt;p&gt;This is a part of an ongoing series on BDD in Sproutcore. You can find the index for the series &lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-intro.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Step 3 - Adding a task&lt;/h2&gt;

&lt;p&gt;The next thing that I would like to be able to do with the todos application is to be able to add a task. In order to accomplish this, I write the following integration test:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773146.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;The only thing new here is the simulating of a mouse click on the button within the run loop inside the test. Within sproutcore, there is no such thing as a native &quot;click&quot; event. Instead, Sproutcore registers a click on a mousedown event, followed by a mouseup. Mike Cohen(FrozenCanuck) has a great blog post explaining the idea, which you can view &lt;a href=&quot;http://frozencanuck.wordpress.com/2010/04/06/simulating-events-in-sproutcore/&quot;&gt;here&lt;/a&gt;. For now, know this is how I simulate a clicking on the button.&lt;/p&gt;

&lt;p&gt;This generates the following failure:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773157.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This means that the page does not have the button currently on it. I add it to the main_page.js:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773164.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This then changes the error to read:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773171.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This tells me that the button is not doing what it is supposed to be doing (adding a task), so I need to implement that functionality. In order to do that, I need to setup the button to target the tasksController, with an action called addTask, which does not yet exist. I modify main_page.js to be the following:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773177.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Again, at this point Sproutcore does not give an error saying that the specified bind function does not exist, but I know that it doesn't, so I add a unit test to implement this functionality:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773180.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This then fails with the following:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773185.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;I add the function to the controller:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773191.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Which changes the failure to the following:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773196.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;To get that test to pass, I add implement the function:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773204.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This causes both my unit tests, and my integration tests to pass, leaving me in the green. As such, it's time for me to clean up the view a bit.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773207.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;&lt;a href=&quot;/2010/01/15/bdd-in-sproutcore-corrections-for-1-3.html&quot;&gt;Corrections for steps 1-3&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>BDD in Sproutcore - Part 2 ~ Viewing the count of tasks</title>
      <link>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-part-2.html</link>
      <pubDate>Sun, 10 Jan 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-part-2</guid>
      <description>&lt;p&gt;This is a part of an ongoing series on BDD in Sproutcore. You can find the index for the series &lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-intro.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Step 2 - Viewing the count of tasks&lt;/h1&gt;

&lt;p&gt;The next feature of the sample todos application that I'd like to implement is the count of todos on the bottom of the page. In order to do this, I'm going to need some more integration tests (apps/todos/tests/integration/viewing_count_of_task.js):&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773028.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This fails with the following errors:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773034.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This is telling me that the summary view does not exist yet, so I create it:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773050.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Which then changes the error message to be the following:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773226.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This tells me that the summary view doesn't have the binding that I want it to have, so I bind it's value to the controller with a function that does not exist yet, but that I wish it had:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773059.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Once I do that, Sproutcore again yields no error, but I know that there is no function countSummary on the tasksController, so I write a failing unit test for that function (app/todos/tests/controllers/tasks.js):&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773072.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Which gives the following failure:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773074.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Which is telling me that I haven't implemented countSummary on the controller, so I implement it:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773076.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Which changes the failure to:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773079.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Which I then make pass by modifying tasksController:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773083.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This makes all the tests pass, which means it's time to clean up the display:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773087.js&quot;&gt; &lt;/script&gt;


&lt;h3&gt;Quick Note&lt;/h3&gt;

&lt;p&gt;What I'm about to do could(or maybe even should) really be put off until we were adding tasks, but since adding tasks is a bit more complicated, I'm going to show it here for the benefit of the beginner.&lt;/p&gt;

&lt;h3&gt;End Quick Note&lt;/h3&gt;

&lt;p&gt;Now, we want that summary to update when there are tasks, so I add an integration test:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773106.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;In order to accomplish that, I add a unit test for the controller:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773107.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;In order to make that pass, I change the tasksController to be:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773110.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Now, there is one more case that I want to cover, and that is when is more than one task, so I add an integration test:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773116.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This fails with the following message:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773123.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;In order to make that pass, I add the following unit test:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773126.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;I use the simplest way I can think of to implement that:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773130.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;And all my tests are passing. However, that countSummary function on the controller isn't really as clean as I would like, so I refactor it to be:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773134.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;And all tests are passing, and when I browse to look at the page, it seems to work as intended when i manually add items into the store.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-part-3.html&quot;&gt;Step 3- Adding a task&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>BDD in Sproutcore - Part 1 ~ Viewing an existing task</title>
      <link>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-part-1.html</link>
      <pubDate>Sun, 10 Jan 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-part-1</guid>
      <description>&lt;p&gt;This is a part of an ongoing series on BDD in Sproutcore. You can find the index for the series &lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-intro.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Step 1: Viewing an existing task&lt;/h1&gt;

&lt;p&gt;The first thing that I would like to do is have the page display an existing task. So I start with the following end-to-end test within a blank project (apps/todos/tests/integration/viewing_task.js):&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772850.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Within the setup, I'm starting the actual application within the page, and creating the existing record which I want to display. Within the teardown, there are two steps that I've found are necessary to &quot;stop&quot; the application. The first is to remove the pane, and the second is to clear the database.&lt;/p&gt;

&lt;p&gt;To begin with here, in order to check that the item is on the page, I'm merely testing that it is within the content of the listView which is going to display the item. I could check here the display is showing the description of the item, and that the checkbox is not checked, but that's a bit more details than I care about at this point.&lt;/p&gt;

&lt;p&gt;In order to run the test, I start up my sc-server, and goto http://localhost:4020/todos/en/current/tests.html. Two tests should initially fail:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772897.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;The first failure is telling me that Todos.Task doesn't exist, so I have to create it (apps/todos/models/task.js):&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772892.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;I rerun my tests, and see that the first failure is now passing, leaving me only with the second:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772899.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This failing test tells me the path for the requested view does not exist, so I have to modify apps/todos/resources/main_page.js to include it:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772909.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This changes the failure to the following:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772921.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;This is telling me that the content of the ListView is null. So what I need to do is bind the contentView to a controller for the tasks, so I do that by modifying the main_page again:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772927.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Here however when I run my tests again, Sproutcore does not give me any kind of error, it just fails silently. I'm not sure why this is (if you have more knowledge of the framework, please enlighten me) because Todos.tasksController doesn't actually exist. But in any case I need to create it (apps/todos/controllers/tasks.js):&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772931.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;When I rerun my tests, I get a different failure:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772937.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;So now my test is telling me that the item is not found in the view. This is because the controller has not had it's content to be set to use Todos.task. In order to ensure that this is happening, I write the following unit test (apps/todos/tests/main_test.js):&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772970.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;In order to make this pass, within the setup I delegate to the store to find the proper object:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772975.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;That makes the unit test that we wrote pass, but the integration test is still failing, so we need to delegate to the controller to set it's content. Here's the unit test to specify that:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772982.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;And to make this pass, I need to implement that delegation:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/772988.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;And that makes all of our existing tests (both unit and integration) pass.&lt;/p&gt;

&lt;h2&gt;Reflection on mocking problems.&lt;/h2&gt;

&lt;p&gt;To be honest, I'm not entirely happy with the mocking that I just did, because I wasn't able to validate what was contained within the messages that were going between the objects. The mock really should be able to do something like wasCalledWith, and give it a parameter. That's what I would generally do in something like Jasmine, but I haven't worked out how to integrate a solid mocking or spying framework with Sproutcore yet.&lt;/p&gt;

&lt;p&gt;Also, I really should have written the delegation to the controller first, but since I knew I couldn't validate what it was called with it would have missed testing that the main function delegated to the store to find the tasks, so I broke the true BDD cycle there. But, I guess it works for now.&lt;/p&gt;

&lt;h2&gt;One last thing before moving on&lt;/h2&gt;

&lt;p&gt;At this point, the view - although it is fully functional - is still quite ugly. Since this is purly aesthetic, I like to wait to style until all my tests are passing. I change main_page.js to be the following:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/773047.js&quot;&gt; &lt;/script&gt;


&lt;p&gt;Generally, since I tend to think of the binding to the description and the value as functionality, I think I would want an integration test which checks both of those values. However for the sake of brevity (this post is already quite long), I'll leave out those tests.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-part-2.html&quot;&gt;Step 2- Viewing the count of tasks&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>BDD in Sproutcore - Introduction</title>
      <link>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-intro.html</link>
      <pubDate>Sun, 10 Jan 2010 00:00:00 PST</pubDate>
      <author>gmoeck@gmail.com (Gregory Moeck)</author>
      <guid>http://gmoeck.github.com/2010/01/10/bdd-in-sproutcore-intro</guid>
      <description>&lt;h1&gt;BDD in Sproutcore&lt;/h1&gt;

&lt;p&gt;Over the last month or so, I've been spending a good amount of my free time using Sproutcore to build some javascript applications. Although I was initially put off by a couple of things, the more I play with the framework, the more I appreciate it. The areas that I originally felt that it was weak have turned out on several occasions to be merely places where my thinking about thick client side applications had to change.&lt;/p&gt;

&lt;p&gt;However one thing that I have found mostly lacking in the community is the ability to use BDD (or really any form of TDD)to drive out the implementation of my applications. For me, this is an absolute must as I'm a big proponent of the craftsmanship movement, and XP. So I've been looking into working out a work-flow for doing BDD within Sproutcore.&lt;/p&gt;

&lt;p&gt;I've put together an example of my work-flow in building the sample todos application. I've chosen to re-implement the functionality of this system because the explanations of the Sproutcore code themselves are available elsewhere, and as such I won't have to to spend much (any?) time explaining how the Sproutcore code is working. If your not sure what the Sproutcore code is doing, I would highly recommend looking at any accompanying information from the wiki which you can view by clicking &lt;a href=&quot;http://wiki.sproutcore.com/w/page/12413071/Todos%C2%A0Intro&quot;&gt;here&lt;/a&gt;. Anything that isn't contained there though I am planning on explaining. I'm also attempting to keep the code as clean as possible, so hopefully it's intent will be self explanatory when combined with the tests.&lt;/p&gt;

&lt;p&gt;I offer this series as an example for beginners who are interested in using BDD principles to drive Sproutcore applications, as well as an opportunity for anyone who has already attempted the same to critique and improve my approach. I genuinely would like criticism as to where both my Sproucore skills, and BDD implementation are lacking.&lt;/p&gt;

&lt;p&gt;I've chosen to use the QUnit based Sproutcore testing framework for both my end-to-end tests as well as my unit tests. I'm aware of Lebowski, and I've tried using it, but it seems (at least at this point) to be a tool that is better fit for verification style testing instead of using the integration tests to drive the unit tests, and features for the application.&lt;/p&gt;

&lt;h1&gt;Breakdown&lt;/h1&gt;

&lt;p&gt;Initially I had this all in a single post, but it seemed way too long, so I've broken it into pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-part-1.html&quot;&gt;Step 1: Viewing an existing task&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-part-2.html&quot;&gt;Step 2: Viewing the count of tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2010/01/10/bdd-in-sproutcore-part-3.html&quot;&gt;Step 3: Adding a task&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2010/01/15/bdd-in-sproutcore-corrections-for-1-3.html&quot;&gt;Corrections for steps 1-3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    

  </channel> 
</rss>
