BDD for C# NUnit

后端 未结 5 1739
甜味超标
甜味超标 2020-12-31 12:09

I\'ve been using a home brewed BDD Spec extension for writing BDD style tests in NUnit, and I wanted to see what everyone thought. Does it add value? Does is suck? If so why

5条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-31 12:54

    I'm going to call out some uses of BDD rather than just the framework, as I think having a really great understanding of unit-level BDD might affect some of the things you create. Overall, I like it. Here goes:

    Rather than calling them PersonAttacksZombieTests, I'd just call them PersonTests or even PersonBehaviour. It makes it much easier to find the examples associated with a particular class this way, letting you use them as documentation.

    It doesn't look like IsStillAlive is the kind of thing you'd want to set on a person; rather an intrinsic property. Careful making things like this public. You're adding behaviour that you don't need.

    Calling new Person(null) doesn't seem particularly intuitive. If I wanted to create a person without a weapon, I would normally look for a constructor new Person(). A good trick with BDD is to write the API you want, then make the code underneath do the hard work - make code easy to use, rather than easy to write.

    The behaviour and responsibilities also seem a bit odd to me. Why is the person, and not the zombie, responsible for determining whether the person lives or dies? I'd prefer to see behaviour like this:

    • A person can be equipped with a weapon (via person.Equip(IWeapon weapon)).
    • A person starts with a fist if they have no weapon.
    • When the person attacks a zombie, the person uses the weapon on the zombie.
    • The weapon determines whether the zombie lives or dies.
    • If the zombie is still alive, it attacks back. The zombie will kill the person (via person.Kill).

    That seems to me as if it's got the behaviour and responsibilities in a better place. Using a different kind of weapon for useless attacks, rather than checking for null, also allows you to avoid that if statement. You'd need different tests:

    • A fist should not kill a zombie when used against it
    • A chainsaw should kill a zombie when used against it
    • A person should use their equipped weapon when attacking a zombie
    • A person should be equipped with a fist if they have no other weapon
    • A zombie should attack back when it's still alive.
    • A zombie should not attack back if it's dead.
    • A zombie should die if killed.
    • A person should die if killed.

    Other than that, it looks great. I like the way you've used the mocks, the flow of strings, and the phrasing of the test methods themselves. I also quite like ProveBy; it's doing exactly what it says on the tin, and nicely ties up the difference between providing examples of behaviour and running them as tests.

提交回复
热议问题