Old Test Code:
1
2
3
4
5
6
| [Test]
public void ShouldCheckRecipientOfReceivedHeaderIsIntranetServer()
{
SetHeaderCollectionCount(2);
Header header1 = CreateMockHeaderAndSetExpectation("Key");
Header header2 = CreateMockHeaderAndSetExpectation("Received"); |
[Test]
public void ShouldCheckRecipientOfReceivedHeaderIsIntranetServer()
{
SetHeaderCollectionCount(2);
Header header1 = CreateMockHeaderAndSetExpectation("Key");
Header header2 = CreateMockHeaderAndSetExpectation("Received");
1
2
| collection.Stub(x => x.get_Item(1)).Return(header1);
collection.Stub(x => x.get_Item(2)).Return(header2); |
collection.Stub(x => x.get_Item(1)).Return(header1);
collection.Stub(x => x.get_Item(2)).Return(header2);
1
2
| factory.Expect(x => x.CreateReceivedHeader(header2)).Return(receivedHeader);
receivedHeader.Expect(x=> x.IsIntranetServer()).Return(true); |
factory.Expect(x => x.CreateReceivedHeader(header2)).Return(receivedHeader);
receivedHeader.Expect(x=> x.IsIntranetServer()).Return(true);
1
2
3
| processor.Process(collection,factory);
receivedHeader.VerifyAllExpectations();
} |
processor.Process(collection,factory);
receivedHeader.VerifyAllExpectations();
}
1
2
3
4
5
6
| [Test]
public void ShouldCheckIfRecipientOfReceivedHeaderCanBeTrusted()
{
SetHeaderCollectionCount(2);
Header header1 = CreateMockHeaderAndSetExpectation("Key");
Header header2 = CreateMockHeaderAndSetExpectation("Received"); |
[Test]
public void ShouldCheckIfRecipientOfReceivedHeaderCanBeTrusted()
{
SetHeaderCollectionCount(2);
Header header1 = CreateMockHeaderAndSetExpectation("Key");
Header header2 = CreateMockHeaderAndSetExpectation("Received");
1
2
3
4
| factory.Expect(x => x.CreateReceivedHeader(header2)).Return(receivedHeader);
collection.Stub(x => x.get_Item(1)).Return(header1);
collection.Stub(x => x.get_Item(2)).Return(header2);
receivedHeader.Stub(x => x.IsIntranetServer()).Return(false); |
factory.Expect(x => x.CreateReceivedHeader(header2)).Return(receivedHeader);
collection.Stub(x => x.get_Item(1)).Return(header1);
collection.Stub(x => x.get_Item(2)).Return(header2);
receivedHeader.Stub(x => x.IsIntranetServer()).Return(false);
1
2
| receivedHeader.Expect(x => x.IsTrustedRecipient()).Return(true);
processor.Process(collection, factory); |
receivedHeader.Expect(x => x.IsTrustedRecipient()).Return(true);
processor.Process(collection, factory);
1
2
| receivedHeader.VerifyAllExpectations();
} |
receivedHeader.VerifyAllExpectations();
}
Can you understand what is happening out here? Well it took me quite some time to understand it all. The first thing that caught my attention was the amount of duplication. All this duplication was getting in the way for me to see what was the real difference between the two tests.
Also I was bothered by the fact that the test contained calls to methods at various different levels of abstraction. I really like creating a veneer of domain specific language (method calls) that the rest of my code interacts with. .i.e. method containing calls to methods which are at similar level of abstraction.
Here is what I came up with to make it easy to communicate the intent. Also I tried to hide all the unnesscary stubbing logic. Not worth it staring in my face.
Refactored Code:
1
2
3
4
5
| [Test]
public void RecipientOfReceivedHeaderBelongingToIntranetServerIsIgnored()
{
AddHeader("MessageId");
AddHeader("Received").FromIntranetServer(); |
[Test]
public void RecipientOfReceivedHeaderBelongingToIntranetServerIsIgnored()
{
AddHeader("MessageId");
AddHeader("Received").FromIntranetServer();
1
2
3
4
5
| [Test]
public void TrustedRecipientOfReceivedHeaderIsAccepted()
{
AddHeader("MessageId");
AddHeader("Received").FromInternetServer().WhichIsTrusted(); |
[Test]
public void TrustedRecipientOfReceivedHeaderIsAccepted()
{
AddHeader("MessageId");
AddHeader("Received").FromInternetServer().WhichIsTrusted();
1
2
3
4
5
| [TearDown]
public void VerifyExceptations()
{
receivedHeader.VerifyAllExpectations();
} |
[TearDown]
public void VerifyExceptations()
{
receivedHeader.VerifyAllExpectations();
}
1
2
3
4
5
| private WhenHeadersAreProcessed FromInternetServer()
{
receivedHeader.Stub(x => x.IsIntranetServer()).Return(false);
return this;
} |
private WhenHeadersAreProcessed FromInternetServer()
{
receivedHeader.Stub(x => x.IsIntranetServer()).Return(false);
return this;
}
1
2
3
4
5
| private WhenHeadersAreProcessed FromIntranetServer()
{
receivedHeader.Expect(x => x.IsIntranetServer()).Return(true);
return this;
} |
private WhenHeadersAreProcessed FromIntranetServer()
{
receivedHeader.Expect(x => x.IsIntranetServer()).Return(true);
return this;
}
1
2
3
4
| private void WhichIsTrusted()
{
receivedHeader.Expect(x => x.IsTrustedRecipient()).Return(true);
} |
private void WhichIsTrusted()
{
receivedHeader.Expect(x => x.IsTrustedRecipient()).Return(true);
}
1
2
3
4
5
6
| private void Process()
{
SetHeaderCollectionCount(headerCount);
factory.Expect(x => x.CreateReceivedHeader(null)).IgnoreArguments().Return(receivedHeader);
processor.Process(collection, factory);
} |
private void Process()
{
SetHeaderCollectionCount(headerCount);
factory.Expect(x => x.CreateReceivedHeader(null)).IgnoreArguments().Return(receivedHeader);
processor.Process(collection, factory);
}
1
2
3
4
| private void SetHeaderCollectionCount(int count)
{
collection.Expect(x => x.Count).Return(count);
} |
private void SetHeaderCollectionCount(int count)
{
collection.Expect(x => x.Count).Return(count);
}
1
2
3
4
5
6
| private WhenHeadersAreProcessed AddHeader(string key)
{
Header header = CreateMockHeaderAndSetExpectation(key);
collection.Stub(x => x.get_Item(++this.headerCount)).Return(header);
return this;
} |
private WhenHeadersAreProcessed AddHeader(string key)
{
Header header = CreateMockHeaderAndSetExpectation(key);
collection.Stub(x => x.get_Item(++this.headerCount)).Return(header);
return this;
}
Also see: Fluent Interfaces improve readability of my Tests
This entry was posted
on Monday, February 9th, 2009 at 3:34 PM and is filed under Agile, Design, Testing.
You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.