Being Cellfish

Stuff I wished I've found in some blog (and sometimes did)

Change of Address
This blog has moved to blog.cellfish.se.
Posts
  • Being Cellfish

    2008 Advent Calendar December 5th

    • 2 Comments
    
    
    1: public class Advent5 : IDisposable 2: { 3: private IFileUtil m_file; 4:   5: public void Dispose() 6: { 7: m_file.Delete(); 8: } 9:   10: [Fact] 11: public void TestReadOK() 12: { 13: // Create a test file 14: m_file = new FileUtil("SomeFile.txt"); 15: m_file.Create("CONTENT"); 16:   17: // Should be able to read file 18: Assert.DoesNotThrow(() => { m_file.Read(); }); 19: } 20:   21: [Fact] 22: public void TestReadFails() 23: { 24: // Create a test file 25: m_file = new FileUtil("SomeFile.txt"); 26: m_file.Create("CONTENT"); 27:   28: m_file.Readable = false; 29:   30: // Should NOT be able to read file. 31: Assert.Throws<AccessViolationException>(() => { m_file.Read(); }); 32: } 33: }

    Now we're using Xunit-net's clean up mechanism, the IDisposableinterface. We still got some redundant code in the setup part of each test. Next I'll refactor that.

  • Being Cellfish

    2008 Advent Calendar December 12th

    • 2 Comments
    
    
    1: public class Advent12 : IDisposable 2: { 3: private IFileUtil m_file; 4:   5: private void SetUp(string content) 6: { 7: m_file = new FileUtil("SomeFile.txt"); 8: m_file.Create(content); 9: } 10:   11: public void Dispose() 12: { 13: m_file.Delete(); 14: } 15:   16: [Fact] 17: public void TestReadReadableFile() 18: { 19: SetUp("CONTENT"); 20: string content = m_file.Read(); 21: Assert.Equal<string>("CONTENT", content); 22: } 23:   24: [Fact] 25: public void TestReadUnreadableFile() 26: { 27: SetUp("SHOULD NOT BE ABLE TO READ THIS"); 28: m_file.Readable = false; 29: Assert.Throws<AccessViolationException>(() => { m_file.Read(); }); 30: } 31: }

    Since the setup-method is called explicitly, why not have several setup-methods for different kinds of setup?

  • Being Cellfish

    SQL crosswords

    • 2 Comments

    I don't know what's worse; making crosswords with only SQL related questions (requires free registration to access) or actually trying to solve the same. This is one of many thing that currently puzzles me. One other thing that also scares me is that I get annoyed when I cannot solve these crosswords right away...

  • Being Cellfish

    Mocks are not Stubs

    • 2 Comments

    As many before me I was recently looking at different mocking frameworks in order to find one that suited my needs, and was written in C++. And there are not many alternatives out there if you're using C++. I've found one open source and two internal (Microsoft staff can access what can be described as an internal codeplex) ones. Pretty soon it turned out that none of these frameworks did what I wanted. Actually they suggested using no framework at all for the situations I was looking to "solve" with a framework.

    At this point I rediscovered an old article by Martin Fowler and it became crystal clear that the reason I didn't find what I wanted in the mocking frameworks was because I really wanted a stub framework (or rather a stub helper). Because what I wanted was a simple way to reuse the algorithm "return 17 the first 7 times called and then throw an exception after that, unless called with argument 4711 in which case you should always return 42". A pretty simple method to write in your stub if you just subclass and override the object you want to mock/stub but a little bit cumbersome in the long run if you do this a lot.

    During a discussion on a company internal mailing list for TDD it became clear that people generally use the term mock object for almost every kind of non-production object used during testing. And when another large group do make the distinction between mocks, stubs, fakes and dummies you quickly run into trouble since you are no longer discussing the same thing. So here is yet another recap on what the different kinds of objects are so I can contribute to the cause, making world a better place to be. At least when talking about mocks & friends.

    Object Description Comment
    Dummy Passed around and should never be used. Should fail the tests if ever used.
    Fake Working implementation but takes short-cuts making them unsuitable for production. For example an in memory database.
    Stub Quickly responds with a small number of known values. Used during testing to mimic a certain behavior.
    Mock I like to think of mocks as stubs with the knowledge of usage added. Used to verify that the user of the (mock)object makes the correct number of calls in the correct order.
    Many mock frameworks are designed to make verification of number of calls and/or order optional. But if you do not verify order or number of calls you're basically using a stub (but it is generated from a mock framework).

  • Being Cellfish

    Object Calisthenics: Rule 4: Use only one dot per line

    • 2 Comments

    Not only is a long line with a lot of dots harder to understand. It usually means that your object is using not only the objects it knows but the objects their "friends" know too. Having only one dot per line does not only make your code more readable. It also helps putting the code in the right place. Consider this method:

    1: public void Update() 2: { 3: context.CurrentSession.Update(); 4: }

    Changing it to this is not the intention of this rule:

    1: public void Update() 2: { 3: Session session = context.CurrentSession; 4: session.Update(); 5: }

    Rather the rule want you to do this:

    1: private void Update() 2: { 3: context.Update(); 4: }

    And here the Update method of the context object has been left out, but it would only call Update on the CurrentSession object. All in all I think this is a rule that is suitable for production code too.

  • Being Cellfish

    Premature optimization is the root of all evil, or is it?

    • 2 Comments

    I've been sitting in a lot of code reviews and code inspections where somebody suggests a change to optimize something. The response from the author is almost always; but that's premature optimization! End of argument... But I almost never hear somebody doing the opposite. I came to think about this again a few days ago when it happened again and just a few hours later I read this post about the subject.

    Premature optimization is not black or white. Some things we know are bad for performance (like memory allocation and copies in a high performance C program) and nobody questions if you optimize that without actual proof it's a problem. As the post above describes it's all about paying a tax up front that is big enough to avoid a large fine later. I don't think the idea behind the quote about premature optimization is about making no optimizations. It's about making a reasonable amount of optimizations. Kind of the same kind of trade-off you have to do when it comes to writing tests. Is it worth adding a test for code that you know will pass just because to document the expected behavior? Sometimes yes, but not always as this post points out.

  • Being Cellfish

    Team Coding Dojo 1

    • 2 Comments

    Today we had our first coding dojo in our team. We did the MineSweeper kata and once again the dojo ended up doing the same thing as usual; got to focused on the end to end tests and string parsing. During the retrospect we concluded that event though we had a short design session in the beginning we didn't really use that design for anything else than naming conventions. We also recognized that the first test written kinds of sets the key for the session. If the first test is testing end to end, then it is easy to continue on that path since you need a second test to refine the design. Instead a better approach is probably to pick some part from the design and start testing that. The school book BDD with outside in demands faking things underneath and if you don't do that you should probably not start outside in - you should to it the classical TDD way; create building blocks as needed - inside out. Or my favorite; middle out...

    But all in all (as usual) I think it was a fun experience and I'm already looking forward to the next session.

  • Being Cellfish

    Do you want to do a good job or do you want to go home?

    • 2 Comments

    A former colleague once said that there are only two types of people; those who want to do a good job and those who want to go home. And it has nothing to do with working over time. The statement is obviously provocative but you should not interpret it literally I think. What it means is that some people go to work, do what they're asked and then go home without necessarily having a passion for what they do. Others are very passionate about what they do and go to work because they love what they do there.

    This to me is just another way of describing software craftsmanship which is being more and more popular lately. And think there are two important aspects of craftsmanship to consider. One is the integrity of being a craftsman. If you want to do a good job you should refuse to do something that you think is a poor solution. Compare yourself with a great chef. A great chef would never serve you something that is not prepared and presented in an excellent way. If you on the other hand just want to go home, just do whatever you need to get home early.

    The other aspect is being proud of what you do. It doesn't mean you have to be proud of code you wrote a year ago or even a few months ago. I've written code I wasn't proud of even a few weeks later. The important part is that you're proud of what you do at least when you write the code. I'd even say that it's a good thing that you're not proud of old things you've done because it means you've improved yourself and that is important. If you however just want to go home, then you're probably not always feel proud about stuff you just did and you're probably proud over things you did ages ago. Because if you just strive to go home then you're probably not improving yourself very fast.

  • Being Cellfish

    On pride and improvements

    • 2 Comments

    So yesterday I wrote about being proud about what you do, but also improving yourself. It made me think about a pretty scary thing that happened to me a few months ago. I was attending this training where we were divided into four teams and worked together for a few days to create an application. At the end of the class at the retrospect I suggested that in future classes each team could present some part of their solution they were proud of and wanted to show to the rest of the class. I said this because I thought my team had learned something and had done a few smart things that I wanted to share. We had some time to spare so the trainer suggested I show what I was thinking about and then the other teams could do the same thing.

    So I showed our stuff and then no other team wanted to show anything. Maybe I'm a little extreme in my search for improvements and maybe I'm over confident in the excellence of our solution but in a room of 25 people I would assume at least somebody felt the same way about something. I don't believe they were all shy. Instead the class went silent and everybody went home. The thing that really scares me is that I think that there is a good chance that the reason for not wanting to show anything actually was that the other teams didn't feel proud about their solution as a whole. Because there was an element of competition there and it's easy to get carried away because it's not real code in the class room...

    Finally I must point out that I do not think you have to do the ultimate solution each time to be proud of your work. I'm sure a master chef sometimes throws together something fast when at home. But I think the mast chef quick lunch probably tastes better than my quick lunch. So the effort needed to be proud might be different for different situations but that hunger for improvements is definitely something I think differentiates the good from the great. So if you do not take pride in anything else, at least take pride in striving to be better and be proud of each improvement.

  • Being Cellfish

    2009 Advent Calendar December 19th

    • 2 Comments

    So far so good but there is one more thing I want the MutexLock to do. The Mutex object may throw an exception (AbandonedMutexException) when being waited for if the current owning thread terminates without releasing the mutex. I want to hide that fact in my MutexLock so I don't need to handle that exception everywhere in my code:

    1: public class Given_an_abandoned_lock : IDisposable 2: { 3: private MutexLock _lock = new MutexLock(); 4: private EventWaitHandle _threadStarted = new EventWaitHandle(false, EventResetMode.ManualReset); 5: private EventWaitHandle _threadStop = new EventWaitHandle(false, EventResetMode.ManualReset); 6: private Thread _thread; 7:   8: public Given_an_abandoned_lock() 9: { 10: _thread = new Thread(() => 11: { 12: _lock.Lock(); 13: _threadStarted.Set(); 14: _threadStop.WaitOne(); 15: }); 16: _thread.Start(); 17: } 18:   19: public void Dispose() 20: { 21: if (_thread != null) 22: { 23: _thread.Abort(); 24: } 25: } 26:   27: [Fact(Timeout=1000)] 28: void It_should_be_possible_to_take_lock_when_thread_dies() 29: { 30: _threadStarted.WaitOne(); 31: _threadStop.Set(); 32: Assert.DoesNotThrow(() => { _lock.Lock(); }); 33: } 34: }

    And that test leads to the following implementation:

    1: public class MutexLock : Lock 2: { 3: private readonly Mutex _lock = new Mutex(); 4:   5: public void Lock() 6: { 7: try 8: { 9: _lock.WaitOne(); 10: } 11: catch (AbandonedMutexException) {} 12: } 13:   14: public void Unlock() 15: { 16: _lock.ReleaseMutex(); 17: } 18: }
Page 5 of 49 (481 items) «34567»