Thursday, December 29, 2011

EasyMock Fundamentals


Introduction

EasyMock is a mock library that can be used as a supplemental tool for a testing framework, such as TestNG, to improve unit testing implementations. EasyMock provides the means (through the use of mock objects) to specify the response that will be returned when the code being tested makes calls to external methods. This will allow the result of the unit test to be isolated from variables outside of the scope of the unit test code.

Refer to the official EasyMock documentation for more detailed explanation of the tool (latest as of this writing EasyMock3.0.Docs).

Note: For the sake of simplicity, not all the details of the code examples have been included.

What is a mock?

Short concise description:
Mocking and Mock Objects is not specific to Java. Mock objects is a unit testing technique in which a code chunk is replaced by dummy implementations that emulate real code. This helps one to write unit tests targeting the functionality provided by the class under test. - reference
For more information, this article offers very good introduction to the concept of mocking:
Mock Objects.

Stubs vs. Mocks

An alternative to using a mock object is to create a stub object; a lightweight implementation of the interface for the external methods, that just return the expected response. These two approaches are best illustrated with an example.

Let us say you want to write a unit test for an object Foo that does something cool, doSomethingCool(), and uses another object, Emailer, to send emails while doing something cool as follows:
package com.partnet.foo;

public class Foo {
  private Emailer emailer;

  public Foo(Emailer emailer) {
    this.emailer = emailer;
  }

  public void doSomethingCool() {
    // something worthy of being unit tested

    emailer.sendEmail(...);
  }
}

package com.partnet.foo;

public interface Emailer {
  boolean sendEmail(...) throw EmailerException;
}
If you're trying to test the doSomethingCool() method, you don't want to, shouldn't have to, and thankfully don't need to worry about what emailer.sendEmail() does (assuming the implementation of the call has no impact on the code you're testing of course).

The assumption here is that the real implementation of Emailer, say it's called FancyEmailerImpl, is a non-simplistic object that may require some configuration or won't work in a non-real environment. In this case you do not want to have to create a real FancyEmailerImpl and use it in your testing because again, what it does has no bearing on the code you're actually trying to test.

Stub Objects

Using the stub object approach, you could create a stubbed-out/dummy version of Emailer like the following:
// stub object
package com.partnet.foo;

public StubEmailer
  implements Emailer
{
  public boolean sendEmail(...) throws EmailerException {
    return true;
  }
}
Simple, easy, done... right? Yep, you can now just setup your unit test as follows and test away:
// stub object use
package com.partnet.foo;

public TestFoo {
  @Test
  public void test() {
    Emailer stubEmailer = new StubEmailer();
    Foo myFoo = new Foo(stubEmailer);

    myFoo.doSomethingCool();
  }
}
The downside to this approach is that you end up building and maintaining a bunch of stub code. Additionally, stub code can be difficult to write as you get into stubbing out more complex objects that you want to test around. For example, if the code you're testing sets an ID on your Emailer and later retrieves it via setId()/getId() methods, this behavior would need to be stubbed out correctly.

Mock Objects

The alternative to writing stubs is writing mocks, or more correctly, using a mock object library to create mock objects for you. EasyMock is such a library. The following demonstrates how to use EasyMock to mock out the Emailer from above.
// mock object example
package com.partnet.foo;

public TestFoo {
  @Test
  public void test() {
    Emailer mockEmailer = EasyMock.createMock(Emailer.class);
    Foo myFoo = new Foo(mockEmailer);

    myFoo.doSomethingCool();
  }
}
Simple, easy, no stub code to maintain. Even cooler is how you solve the problem mentioned above regarding setId()/getId(). This is where the concept of Expectations comes in (in terms of EasyMock, these are called IExpectationSetters). An Expectation is basically you telling a mock object how to behave and what you expect to happen when you run the unit test code: "When this happens, do this", "When your getId() method is called, return this value", "I expect that your setId() method will be called". After your unit test code has run, you can then ask EasyMock to verify that everything you expected to happen actually occurred so that you can be assured your code does what you think it does.

Downloads

The latest EasyMock files can be downloaded from a link on the EasyMock Download page.

Integration

Add these to the classpath:
  • easymock.jar
  • cglib (2.2) - to perform class mocking
  • Objenesis (1.2) - to perform class mocking
EasyMock only works with Java 1.5.0 and above.

Writing Tests

Basic steps for EasyMock use

  1. import EasyMock
    • import static org.easymock.EasyMock.*;  // non-static imports may also be used
  2. create mock object
    • private ClassOrInterface mock;
    • mock = createMock(ClassOrInterface.class);  // throws AssertionErrors for all unexpected method calls
    • mock = createNiceMock(ClassOrInterface.class);  // allows all method calls and returns appropriate empty values (0, null or false)
  3. specify expectations for mock (in other words, "I'm going to tell you what you should expect to do")
    • mock.doThis();
    • mock.doThat();
    • specify that the last method could be called x times
      • expectLastCall().once();  // default one call
      • expectLastCall().times(3);  // exact calls
      • expectLastCall().times(2, 5);  // min, max calls
      • expectLastCall().atLeastOnce();  // one or more times
      • expectLastCall().anyTimes();  // 0 or more times
    • specify method response or return value
      • expect(mock.doThis()).andReturn(returnValue, i.e. "true");
  4. make mock available for use (in other words, "I'm done telling you what you should expect to do, now get ready to do it.")
    • replay(mock)
  5. run unit test that will call doThis() and doThat()
    • verify proper response
      • assertTrue(doThis());
  6. verify that expected behavior was called (did everything get called the expected number of times?)
    • verify(mock)

Tips

Prefer Nice Mocks

There are basically 3 different ways to have EasyMock create a mock object for you.
  1. createMock(Foo.class)
  2. createNiceMock(Foo.class)
  3. createStrictMock(Foo.class) 
Each way gives you a mock object with slightly different behaviors/restrictions. Consult the EasyMock API for specifics, but unless you have valid reason to not, the preferred method is createNiceMock(). Nice mocks are, as their name suggests, 'nice'. 'Forgiving' is probably a more appropriate term in that, as the API states, nice mocks will return 0, false, or null for unexpected invocations. Meaning:
  • for methods that return int, double, long, char, float, byte, short (non\-boolean primitives) - the returned value is 0 
  • for methods that return boolean (not sure about Boolean) - the returned value is false 
  • for methods that return Object (or anything that extends Object) - the returned value is null 
The benefits are not obvious without further explanation. Try to think of it in these terms. Nice mocks allow you to configure them the way you want for the behavior you care about without having to configure them for the behavior you don't care about and are not relying on for your test. For example, let's assume you want a mock for an object that has a getId() method. Chance are you don't care what getId() does and if the code you're testing doesn't care what it does, but happens to call it in a log statement or something that is irrelevant to your test, then a nice mock will allow you to not have to setup an expectation for that method (see Example 1).
package com.partnet.foo;

public class Foo {
  private Emailer emailer;

  public void doSomethingCool() {
    // I don't care about this and don't want to setup an expectation for it
    log.debug("emailerId:" + emailer.getId());

    // something worthy of being unit tested
    emailer.sendEmail(...);
  }
}
Additionally, if another developer were to remove that log statement, the unit test wouldn't have to change because the expectation was never added and the tests wouldn't break just because a log statement was removed.

Prefer "Relaxed" Expectations

The term "relaxed" refers to the IExpectationSetters API as it relates to configuring the number of times an expectation is valid. Specifically, the methods once(), times(count), and times(min, max) should be avoided unless you really care and/or your test relies on them. The methods anyTimes() and atLeastOnce() should be used instead. These "execution count" methods set the number of times a given method is expected to be called. The reason the latter methods should be preferred is that, while setting up explicit method call counts is certainly valid, implementations change over time and often times those changes have no effects on the functionality of a given object. For example, who cares how many times emailer.getId() is called in the above example and does the fact that it gets called multiple times have any effect on the calling code? Clearly not. However, if an expectation like the following was added:
EasyMock.expect(mockEmailer.getId()).andReturn(1).once();
and later the log statement was removed or an additional log statement was added that called getId() again, the unit test would fail.

However, this practice is not an across-the-board standard as it makes sense to setup an expectation like the following:
EasyMock.expect(mockEmailer.sendEmail(...)).andReturn(true).once();
because sending multiple emails is most likely not expected or okay.

NOTE: not specifying one of the "execution count" methods is the same as using the once() method (i.e. once() is assumed unless otherwise instructed).

Stub Returns

andReturn() vs. andStubReturn()

EasyMockSupport

Introduced in version 2.5.2, EasyMockSupport is your friend. It saves you the trouble of having to call reset(), replay(), and verify() on all your mock objects. As the javadoc shows, an example usage is as follows:
package com.partnet.foo;

public class TestFoo
  extends EasyMockSupport {  // this is key

  @Test
  public void test() {
    resetAll();  // reset all existing mocks

    // create mocks
    firstMock = createMock(A.class);
    secondMock = createMock(B.class);

    replayAll();  // put all mocks (new & existing) in replay mode

    // use mocks

    verifyAll();  // verify all mocks (new & existing)
  }
}

Mock Builders

See [some future post] for how cool this feature is.

Argument Matching

Argument matching is related to setting up expectations and is one of those subtleties of EasyMock that you might miss and certainly not understand until you really start writing tests.

The following shows setting up an expectation without any argument matchers:
EasyMock.expect(mockEmailer.sendEmail("foodaddy")).andReturn(true);
In this scenario, you're telling EasyMock to return true when sendEmail() is called with "foodaddy" as the parameter. Simple enough, but what if you wanted tell EasyMock to return true for all parameter values, or only certain parameter values, or only on Tuesdays, etc? This is where argument matchers come to play.

The following demonstrates an argument matcher that matches all String values:
EasyMock.expect(mockEmailer.sendEmail(EasyMock.isA(String.class))).andReturn(true);
What about all String values except "foodaddy"?
EasyMock.expect(mockEmailer.sendEmail(
    EasyMock.not(EasyMock.eq("foodaddy")))).andReturn(true);
EasyMock supports a wide selection of argument matchers that can be used to create any type of matcher. Here are some of the matcher methods:  anyInt(), anyObject(), contains(), eq(), geq(), gt(), isA(), leq(), lt(), same(), startsWith().

Argument matchers can be combined using the following methods:  and(), or(), not()

Consult the API for a complete listing, but as an example:
// true for "foodaddy" or "foo.*daddy"
EasyMock.expect(mockEmailer.sendEmail(
    EasyMock.or(EasyMock.eq("foodaddy"),
        EasyMock.and(EasyMock.startsWith("foo"),
                     EasyMock.endsWith("daddy")))
        )).andReturn(true);
EasyMock even has support for creating custom argument matchers. Consult the API for more info. For more info on argument matchers, see this blog post.

Argument Matching part 2

EasyMock has this annoying feature/limitation that prevents mixing non-argument matchers (raw values) with argument matchers when setting up expectations. I often encounter this when trying to setup expectations for a method that takes multiple parameters where some are simple primitives and others are complex types. This can be annoying because often times you want to be able to setup your expectations in this way. Given the following:
public interface Emailer {
  boolean sendEmail(String emailAddress, String message);
}

public class Foo {
  private Emailer emailer;

  public Foo(Emailer emailer) {
    this.emailer = emailer;
  }

  public void doSomethingCool(boolean useDefault, String emailAddress) {
    String message = null;
    if (useDefault) {
      message = "default message";
    }
    else {
      message = "something else";
    }
    emailer.sendEmail(emailAddress, message);
  }
}
So now you want to test this code so you start as follows:
public class TestFoo {
  @Test
  public void test_doSomethingCool()
  {
    final String emailAdrs = "foo@foodaddy.com";

    Emailer mockEmailer = EasyMock.createMock(Emailer.class);

    // return true when emails are sent to foo@foodaddy.com
    // regardless of the message being sent
    EasyMock.expect(mockEmailer.sendEmail(
        emailAdrs, EasyMock.isA(String.class))).andReturn(true);

    EasyMock.replay(mockEmailer);

    Foo myFoo = new Foo(mockEmailer);
    myFoo.doSomethingCool(true, emailAdrs);

    EasyMock.verify(mockEmailer);
  }
}
As the comment above states, you don't care what message is being sent to "foo@foodaddy.com". You want all emails sent to "foo@foodaddy.com" to return true. Seems valid enough, but when you run your test, you'll get an error message similar to this:
java.lang.IllegalStateException: 2 matchers expected, 1 recorded. This exception usually occurs when matchers are mixed with raw values when recording a method: You need to use no matcher at all or a matcher for every single param:

Huh? The key is "..._matchers are mixes with raw values_...". Unfortunately, you can't do what you were hoping to do. EasyMock requires that you use ALL raw values or ALL argument matchers in a given expectation. So the following shows how you accomplish this:
public class TestFoo {
  @Test
  public void test_doSomethingCool()
  {
    final String emailAdrs = "foo@foodaddy.com";

    Emailer mockEmailer = EasyMock.createMock(Emailer.class);

    EasyMock.expect(mockEmailer.sendEmail(
        EasyMock.eq(emailAdrs), EasyMock.isA(String.class))).andReturn(true);

    EasyMock.replay(mockEmailer);

    Foo myFoo = new Foo(mockEmailer);
    myFoo.doSomethingCool(true, emailAdrs);

    EasyMock.verify(mockEmailer);
  }
}
The eq() argument matcher is what's needed here and is especially handy at matching primitive values. The eq() argument matcher can certainly be used to match more complex types, but with primitives, you don't have to worry about the implementations of equals() and hashCode() as discussed next.

Captures

These are cool, but the documentation and examples I've found are not. I like examples so hopefully the following will demonstrate Capture's coolness. Given the following:
public class Recipient {
  private String name;
  private String email;

  public Recipient(String name, String email) {
    this.name = name;
    this.email = email;
  }

  // getters for above attrs
}

public interface Emailer {
  boolean sendEmail(Recipient r, String message);
}

public class Foo {
  private Emailer emailer;

  public Foo(Emailer emailer) {
    this.emailer = emailer;
  }

  public void doSomethingCool(boolean useDefault) {
    Recipient r = null;
    if (useDefault) {
      r = new Recipient("foodaddy", "foo@part.net");
    }
    else {
      r = new Recipient("noreply", "noone@part.net");
    }
    emailer.sendEmail(r, "some message");
  }
}
So the question is, how would you test the doSomethingCool() code and ensure that the if/else conditional evaluation is being done correctly? Granted, this is a simple example, but the question is still valid. There are 2 possibilities.
  • 1) Implement equals() and hashCode() on the Recipient object so that their implementation, specifically equals(), could be used in your unit test as follows.
public class TestFoo {
  @Test
  public void test_doSomethingCool()
  {
    {
      Recipient recOne = new Recipient("foodaddy", "foo@part.net");
      Emailer mockEmailer = EasyMock.createMock(Emailer.class);

      // this next line is the key - we're relying on the fact that
      // recOne.equals(recipient) == true - where recipient is the
      // one created in doSomethingCool()
      EasyMock.expect(mockEmailer.sendEmail(recOne, ...)).andReturn(true);

      EasyMock.replay(mockEmailer);

      Foo myFoo = new Foo(mockEmailer);
      myFoo.doSomethingCool(true);

      EasyMock.verify(mockEmailer);
    }

    {
      Recipient recTwo = new Recipient("noreply", "noone@part.net");
      Emailer mockEmailer = EasyMock.createMock(Emailer.class);

      // same comment as before
      EasyMock.expect(mockEmailer.sendEmail(recTwo...)).andReturn(true);

      EasyMock.replay(mockEmailer);

      Foo myFoo = new Foo(mockEmailer);
      myFoo.doSomethingCool(false);

      EasyMock.verify(mockEmailer);
    }
  }
}
As was noted in the code, the key is that we're relying on the implementation of Recipient.equals().

On the test code line:
mockEmailer.sendEmail(recOne, ...);
two things are occurring:
  1. You are setting up an expectation that the sendEmail() method will be called
  2. The Recipient that is passed to sendEmail() will be equal to the one provided. 
Even though the same Recipient object instance (recOne != recipient) is not used in the expectation, the two different instances are considered equal:
recOne.equals(recipient) == true
By not including an argument matcher explicitly, EasyMock is using object equality (equals()) to match. This is the same as using the eq() argument matcher.

While this approach is certainly valid, it's less than ideal because it requires that equals() be implemented. Furthermore, the implementation of equals() has to be known and understood how to be taken advantage of (i.e. you have to know that name and email are used in equals() rather than something like an id attribute). Additionally, you're not able to actually test/assert against the attribute values of the created Recipient. That's essentially what's being done by taking advantage of the implementation of equals(), but it's less explicit and obvious to the poor maintenance developer.
  • The second (and better) approach is to use an EasyMock Capture as follows to retrieve, err capture, the actual instance of the Recipient object created by the doSomethingCool() method.
public class TestFoo {
  @Test
  public void test_doSomethingCool()
  {
    {
      Emailer mockEmailer = EasyMock.createMock(Emailer.class);
      
      Capture rCap = new Capture();

      EasyMock.expect(mockEmailer.sendEmail(
          EasyMock.capture(rCap), ...)).andReturn(true);

      EasyMock.replay(mockEmailer);

      Foo myFoo = new Foo(mockEmailer);
      myFoo.doSomethingCool(true);

      EasyMock.verify(mockEmailer);
      
      // actual Recipient instance returned here
      Recipient recipient = rCap.getValue();
      
      Assert.assertEquals(recipient.getName(), "foodaddy");
      Assert.assertEquals(recipient.getEmail(), "foo@part.net");
    }

    {
      Emailer mockEmailer = EasyMock.createMock(Emailer.class);

      Capture rCap = new Capture();

      EasyMock.expect(mockEmailer.sendEmail(
          EasyMock.capture(rCap), ...)).andReturn(true);

      EasyMock.replay(mockEmailer);

      Foo myFoo = new Foo(mockEmailer);
      myFoo.doSomethingCool(false);

      EasyMock.verify(mockEmailer);

      // actual Recipient instance returned here
      Recipient recipient = rCap.getValue();
      
      Assert.assertEquals(recipient.getName(), "noreply");
      Assert.assertEquals(recipient.getEmail(), "noone@part.net");
    }
  }
}
Using a Capture has none of the requirements/drawback/quirks as the first approach and is certainly no harder to use.

Links

Tuesday, December 27, 2011

Worry

My Dad was always telling me not to worry about Jess when we were younger and he (my dad) was around.

So we're all (CJ, Alex, Jo, me) downstairs last night picking up toys... except Alex of course is playing with toys.  Christopher keeps telling Alex to stop playing because it's time to pick up.  I tell CJ to relax that mommy and daddy will take care of Alex.  CJ continues to be bothered by Alex's playing.
CJ: Alex, STOP playing!
Me:  Christopher, don't worry about Alex.  You worry about you.
CJ: But I have to worry about Alex because he's my baby brother.
The tears of joy swell in my eyes... and as I write this.

Saturday, December 24, 2011

Wise Words of Tecumseh (Shawnee)

This was read as part of my uncle Gary's funeral service:
Live your life that the fear of death can never enter your heart.
Trouble no one about his religion.
Respect others in their views and demand that they respect yours.
Love your life, perfect your life, beautify all things in your life.
Seek to make your life long and of service to your people.
Prepare a noble death song for the day when you go over the great divide.
Always give a word or sign of salute when meeting or passing a friend, or even a stranger, if in a lonely place.
Show respect to all people, but grovel to none.
When you rise in the morning, give thanks for the light, for your life, for your strength.
Give thanks for your food and for the joy of living.
If you see no reason to give thanks, the fault lies in yourself.
Touch not the poisonous firewater that makes wise ones turn to fools and robs their spirit of its vision.
When your time comes to die, be not like those whose hearts are filled with fear of death, so that when their time comes they weep and pray for a little more time to live their lives over again in a different way.
Sing your death song, and die like a hero going home.

Friday, December 23, 2011

Garileo Pedroza

Hubs and Dad
Kearns, UT-Gary was born September 6, 1956 to Frank and Beverly Pedroza in Murray, Utah he married Ann in 1981 and they have two wonderful sons, Philip and Issac. He is the third of four brothers. Although he is free of the pain of arthritis, it was not a peaceful passing. He fought like hell to stay as he felt that he had work to do and that he needed to take care of his little family, multitude of friends and cohorts. His passing has left a large hole in many people and places. He left us all way too early. He is preceded in death by his parents. Survived by his wife, sons, brothers and a multitude of aunts, uncles and cousins.
 

Gari grew up in Kearns, Utah. He attended Kearns Jr. High and was student body president, inspiring many, and helping transform the Kearns High graduating class of 1974 into one of the closest classes ever. Gari went on to graduate from the "U" in planning, working as an intern for SLC and then as a planner at Price, Utah. As the arthritis began to take a toll on his body, he worked from home turning his "avocation" into his "vocation", consulting and connecting people on various projects relating to his geometries with the intent of helping the world.
 

Gari loved camping and the mountains. Because he could no longer hike he had to content himself with driving to the various vacation areas, speeding by rest areas with a vengeance! Everyone learned quickly not to drink any beverage while on the drive with "G"!
 

Gari always honored Christmas and kept it in his heart the whole year. It is appropriate that he left with the angels this time of year.

Tuesday, December 06, 2011

The Last Symbol

I've decided I need to start keeping track of the books I read.

Author: Dan Brown
Much like the other books by Brown that I've read (The DaVinci Code and Angels & Demons) which isn't saying much as it involves the same character, Robert Langdon. I certainly enjoyed the book and was able to breeze through it quite rapidly including some late nights where I couldn't put it down.  Brown's short chapter switching back and forth between plot lines contributes to that quite a bit. It made we want to go back to Washington DC for another trip and see some specific sites.

Sunday, October 02, 2011

Halloween Hat

Jo has put out a few Halloween decorations around the house including a couple plastic witch's caldrons.  Today, Christopher decided that one in particular makes a great hat.  He was playing with it on his head and decided to push to down all the way... all the way, over his ears and eyes.  He thought that was pretty funny.  Thing was though that it was tight fit so when it came to taking off his head, he kinda started freaking out and really struggled with getting it off.  Additionally, he want any help getting it off so Jo and I sat there laughing hysterically.  I looked for the camera, but wasn't fast enough.

Saturday, October 01, 2011

Dizzy Trucks

Christopher calls cement trucks "Dizzy trucks".  Yes, I know there's a Bob the Builder character that is a cement truck called "Dizzy", but I still think it's cute.

Sunday, August 28, 2011

Semi-Recent House Projects


Thanks to my handy contractor, Dennis, we now have more master bathroom storage, 3 new ceiling fans, and a newly textured ceiling (the last one in the house) in our other upstairs bathroom.  The work in the other bathroom was a result of the job K-Bar did for us, which I'm still not happy about.  Dennis had to fix the ceiling cracks, patch the wall, texture the ceiling, and paint nearly the entire bathroom.  All that work and it cost us no small amount.  Thankfully, Dennis always does great work, and we're always happy with the results.  I will definitely call him next time before looking elsewhere.

The fans have been nice this summer since it's been so hot, and the boys have gotten a kick out of them.  My only complaint is that I keep bumping into the chain with my head.

Something else I did all by myself was to mount one of those cheap push lights on the bottom of the new bathroom cabinet for those late nights visit.  That way, there's no blinding light experience for the visitor.









Posted by Picasa

Monday, June 27, 2011

Biking Dimensional Analysis

Given:
  • bike price  = 500 dollars
  • gas price = 3.50 dollars/gal
  • gas mileage = 19 miles/gal (source)
  • commute distance (round trip) = 10 miles
500 dollars * (1 gal/3.50 dollars) * (19 miles/1 gal) * (1 day/10 miles) = 271.4 days

Based on that, I need to ride my bike 272 days to pay for my bike.

Monday, June 20, 2011

Lambourne House Projects

My intention is to capture these things as they happen rather than having to think back to them years later.

  1. Come to find out, none of the grout in the house had been sealed by the flippers.  Damn them!  Thanks to Madd Construction and $150 (plus the $90 for 5 years of sealer), the grout is now sealed.  Apparently, this is a project that they recommend (especially in the bath surrounds) that I do annually.
  2. Kids bathroom didn't have a fan, which the inspector pointed out to his credit.  Called around and got 2 estimates.  K-Bar put the fan in (and moved the light switch into the bathroom) for $525 but left me with more of a project than I started with.  Now I need to have the plaster repaired around the new switch and the ceiling patched.  Even better, we determined the bathroom ceiling has painted-over wallpaper that has to come down.  As a side note, I went the rounds with the owner of K-Bar in regards to my servicemagic review.  Morale of that story, you do a C+ job, you get a C+ rating.
  3. Inspector pointed this one out as well.  House didn't have any rain gutters, which was very apparent this Spring with all the rain we've had.  After consulting with a foundation specialist company (Intermountain Foundation Repair), I got 2 bids for this job and liked both companies (Ace Gutter and Rain Gutter Specialties), but decided to go with Ace for a few reasons.  They actually ended up having to cut out a section of my drive way so they could put in a drain system, but it was expected and I think it was the best decision.  All and all, the project ($1850) cost less than I had anticipated, and I'm happy with the results.

Monday, May 09, 2011

45 Lessons

Written by Regina Brett, 90 years old, of the Plain Dealer, Cleveland, Ohio.

To celebrate growing older, I once wrote the 45 lessons life taught me. It is the most requested column I've ever written. My odometer rolled over to 90 in August, so here is the column once more:
  1. Life isn't fair, but it's still good.
  2. When in doubt, just take the next small step.
  3. Life is too short to waste time hating anyone.
  4. Your job won't take care of you when you are sick. Your friends and parents will. Stay in touch.
  5. Pay off your credit cards every month.
  6. You don't have to win every argument. Agree to disagree.
  7. Cry with someone. It's more healing than crying alone
  8. Its OK to get angry with God. He can take it.
  9. Save for retirement starting with your first paycheck.
  10. When it comes to chocolate, resistance is futile.
  11. Make peace with your past so it won't screw up the present.
  12. It's OK to let your children see you cry.
  13. Don't compare your life to others. You have no idea what their journey is all about.
  14. If a relationship has to be a secret, you shouldn't be in it.
  15. Everything can change in the blink of an eye. But don't worry; God never blinks.
  16. Take a deep breath. It calms the mind.
  17. Get rid of anything that isn't useful, beautiful or joyful.
  18. Whatever doesn't kill you really does make you stronger.
  19. It's never too late to have a happy childhood. But the second one is up to you and no one else.
  20. When it comes to going after what you love in life, don't take no for an answer.
  21. Burn the candles, use the nice sheets, wear the fancy lingerie. Don't save it for a special occasion. Today is special.
  22. Over prepare, then go with the flow.
  23. Be eccentric now. Don't wait for old age to wear purple.
  24. The most important sex organ is the brain.
  25. No one is in charge of your happiness but you.
  26. Frame every so-called disaster with these words 'In five years, will this matter?'
  27. Always choose life.
  28. Forgive everyone everything.
  29. What other people think of you is none of your business.
  30. Time heals almost everything. Give time.
  31. However good or bad a situation is, it will change.
  32. Don't take yourself so seriously. No one else does.
  33. Believe in miracles.
  34. God loves you because of who God is, not because of anything you did or didn't do.
  35. Don't audit life. Show up and make the most of it now.
  36. Growing old beats the alternative -- dying young.
  37. Your children get only one childhood.
  38. All that truly matters in the end is that you loved.
  39. Get outside every day. Miracles are waiting everywhere.
  40. If we all threw our problems in a pile and saw everyone else's, we'd grab ours back.
  41. Envy is a waste of time. You already have all you need.
  42. The best is yet to come...
  43. No matter how you feel, get up, dress up and show up.
  44. Yield.
  45. Life isn't tied with a bow, but it's still a gift.
 Friends are the family that we choose

Wednesday, March 09, 2011

House Projects Completed Over the Years

In no particular order and in addition to the ones listed here:
  1. Kitchen - Replaced butcher-block counters in kitchen.  At the same time, replaced aluminum sink, crappy faucet, and garbage disposal (a couple companies).
  2. Kitchen - Replaced the oldest dishwasher in the world (RC Willey guy).
  3. Kitchen - Moved kitchen cabinet above stove up so that new microwave could be placed below cabinet (Dennis).
  4. Kitchen - Removed half wall / old window seat in kitchen to allow walk through access from back door.  I did this one myself with some electrical help from Dale.
  5. Kitchen - Added pantry, coat closet, and spice cabinet in hallway west of kitchen. Team effort here.  Mike Knodel (wouldn't recommend), Dennis, and I all contributed at various points.
  6. Kitchen - Added spacers between cabinet doors (me).
  7. Kitchen - Added cabinet hardware (me).
  8. Kitchen - Replaced 2 drawers that were falling apart (Blair).
  9. Kitchen - Added bar to hang towels and added curtain to hide crap (me).
  10. Kitchen - Fixed bottom cabinet frame under the sink (me).
  11. Master bedroom - Added new 3/4 master bathroom.  This cost us one of our walk-in closets, but it was well worth it (Kirk).
  12. Master bedroom - Removed murphy bed, removed carpet, refurnished hardwood floors, added ceiling fan and new light fixture, and painted walls in north bedroom.  This became our master bedroom after this project (me and Jess and a palm sander).
  13. Main level - Replaced pedestal sink with vanity and new sink (Jess - he wouldn't let me pay him).
  14. Main level - Insulated under-window bench storage (me). 
  15. Main level - added coat hooks by front door (me).
  16. Main level - Cut vents in door to basement (me).
  17. Stairs - Had open stairs closed in with custom plexiglass and balusters.  At the same time, the open shelving at the top of the stairs was also closed in (Scott).
  18. Laundry room - Had flexible dryer venting replaced with hard-piping (Madd Construction).
  19. Upstairs bath area - Removed carpet in upstairs bathroom and replaced with tile - we did this one ourselves.  We did it over Memorial Day our first year in the house (me and Jo).
  20. Upstairs bath area - Replaced wall-mounted sinks with custom-made vanities (Blair).
  21. Upstairs bath area - Stained loft ladder (me and Blair).
  22. Upstairs bath area - Had new linen closet built and installed in the void next to the south sink area (Dennis).
  23. South bedrooms - Replaced old ceiling fans with new ones with lights (me).
  24. General - Replaced window coverings throughout the house (me).
  25. General - Nearly every wall in the house has been repainted as well as a few ceilings.  We never got around to having all the trim and molding painted though (me & Jo did most of it; we hired out the entry way).
  26. General - Replaced all carpet throughout (except loft and master closet).
  27. General - Replaced high-flow toilets (2) with new low-flow ones (Kirk).
  28. General - Added extra blown-in insulation to attic (Insulation company).
  29. Outside - Added deck (me and dad).
  30. Outside - Removed landscaping berm, old parking concrete, and backyard grass.  Replaced with new driveway concrete (stamped concrete including in the front yard off the porch) and auto pavilion. (Demo guy, Booker & Travis, etc)  Pics
  31. Outside - Added soffit and fascia to auto pavilion (Soffit company).
  32. Outside - Painted (sprayed) under side of auto pavilion roof (me).
  33. Outside - Painted main support beams of auto pavilion (me and dad).
  34. Outside - Added gutters around auto pavilion (Gutter company).
  35. Outside - Replaced gutters around front porch (Gutter company).
  36. Outside - Removed grass, bushes, and pine tree in front yard.  Replaced with bark and landscaping plants. (Me, Greg, Kyle, dad)
  37. Outside - Removed HUGE cottonwood tree on the west property line.  Luckily, we were able to split the $1800 expense 3 ways with west neighbors and Greg & Kyle (Tree company).
  38. Outside - Added mini-roof over back door awning (me).
  39. Outside - Repainted entire area around back door and the columns next to house (me).
  40. Outside - Refinished porch (me and Blair).
  41. Outside - Added BBQ platform outside back door (me).
  42. Outside - Replaced damaged soffit and fascia on roof (Roof guy).
  43. Outside - Added vinyl coating to inside of swamp cooler tray (me).
  44. Outside - Added brass kick plates on front and back doors (me).
  45. Outside - Added rock groupings in park strip (me).

Thursday, February 24, 2011

Planned Parenthood

 I'm sorry, but I feel I have to somehow respond to an email I just received.

Following is a list of services/information you can find on Planned Parenthood's website:
You may or may not agree with the complete list, but I would argue that you cannot disagree with all of them and that you most likely agree with at least one of them.  Regardless, please do your own research and information gathering on any and all topics before forming an opinion and passing judgment.  In fact, try to beware judgment altogether.

Oh, and please take me off your mailing list.

Sunday, February 20, 2011

Words of Wisdom for 350 Edith

  • There are 5 smoke alarms in the house (the 2 hard ones to find are in the vaults of the south bedrooms), and they are interconnected such that if one detects smoke, they all go off. 
  • Learn about and understand how the boiler works, and the manual adjustments that can be made if/when necessary.  Tingey Plumbing is a great resource and has worked on the system in the past.
  • The easiest way to get on the roof is by using 2 ladders (or the same one twice).  Use one ladder to get on top of he porch.  Use the other ladder to get on top of the roof in the south west valley.
  • The sprinkling system in the back needs some attention.  Since the carport was put in, I don't trust that the pipes that run under the driveway aren't broken.  I'm sure a sprinkler company could do something to determine the status of the pipes.
  • When it gets really windy, you may hear an odd knocking noise that may concern you.  The first time I heard it, I was concerned and found myself outside at o'dark thirty investigating the noise in my pajamas.  I thought it was the gate on the fence backing against itself.  It wasn't.  The noise is the large blue spruce tree on the south east corner of the house bumping against the house.  I've asked a tree guy about this and have been told that it's not a concern.
  • The upstairs living room has a set of double pocket doors that have been trimmed in.  "Trimmed in" meaning that a piece of trim was added to hide the pocket opening where the doors are.  We never, ever closed the doors when the opening wasn't trimmed in and so it just made sense to add a more finished look.
  • When we had the carport and new driveway put in, we added a 4" conduit pipe that runs from the base of the utility pole in the back yard to the south west corner of the house.  Our intention was that we could have the power lines that hang in the air re-routed through the conduit.  We never got around to it, but always felt it would be a nice change to make.
  • It was always our intention to have lights added to the carport.  With that in mind, we ran another conduit under the deck to the south west corner of the house over to and up the middle support column of the carport.  We actually ran the electrical line through the conduit at the same time, but I'm not sure we ran the proper electrical line.

    Tuesday, February 15, 2011

    House projects completed

    Following is a list of house projects we've done to get our house ready:
    1. dining room floor trim
    2. paint bedroom trim
    3. upstairs tv room doors - trim & paint
    4. clean up alex bedroom wall
    5. back door floor mat
    6. paint downstairs yellow
    7. paint dining room base boards
    8. paint great room
    9. paint ceiling in front room
    10. paint ceiling in upstairs tv room
    11. paint loft ceiling
    12. paint closet/pantry
    13. paint spice cabinet
    14. paint master bedroom crack (south wall)
    15. paint half wall at top of stairs (gate repair)
    16. bottom of stairs missing trim
    17. paint mirror
    18. misc floor repair
    19. dining room floor
    20. replace sconces and other fixtures
    21. cork board trim
    22. replace 2-way deadbolts
    23. add front and back door kick plates
    24. remove & replace bathtub silicone
    http://goo.gl/MPzzV

      Friday, February 04, 2011

      Grandma Bev

      Gandma Bev passed away earlier this morning around 2:00 AM.  My dad called around 7:30 to tell me the news.  He had been over to see her last night and stopped by before heading home.  He said he didn't think she'd live through the weekend.  My grandma was 82 and had been sick for some time.  I think to say she lived a full life is a fair statement.

      Death is a strange thing.  It certainly makes you stop and think.  My dad and uncles were trying to plan the funeral when I saw them earlier this evening.  I don't think that's something you should leave to your kids.  I think it's important to have that stuff in order so that you can have things the way you want and so that a burden is placed on those that you leave behind.

      For me, I don't want a viewing and I want to be cremated (haven't decided if it's important what happens to my ashes).  I want people to remember me for who I was in life, not in death.  Additionally, I don't see any reason in being laid in the ground.  Cemeteries are such an odd thing to me.  I just don't get it.  I can understand having a place where people go to remember me, but why a cemetery?  I'm sure that statement is somehow against my religion, but I really don't care.

      As I said above, no plans have been made for my grandma's funeral yet, but I choose to remember my grandma for who she was and what she meant for my family.  Many a Christmas memory took place at her house.  I will try to hold on to those memories over the years, but I'm certain they will fade.  Many a recipe has been lost and not enough pictures and conversations were had.  I look to the future with hope, but will occasionally revisit the memories of the past.  May God rest your soul, Grandma.