Skip to content

Instantly share code, notes, and snippets.

@rhwy
Last active December 26, 2015 19:19
Show Gist options
  • Save rhwy/7200410 to your computer and use it in GitHub Desktop.
Save rhwy/7200410 to your computer and use it in GitHub Desktop.
Following my tweet discussion https://twitter.com/rhwy/status/394729592118071296, let's put some code to clarify inputs. The code is in C# but near to pseudo-code and other languages to be clear for all (I hope :-) I tend to be the more specific as possible but sometimes I smell that it should be over-engineered too. As usual it depends on the c…
//Imagine you have a Cart with items you can add into
public class Cart
{
public int Id {get;private set}
public List<CartItem> Items {get;private set}
public Cart(int id) { Id = id;}
//while writing your tests, you (want to) arrive to these checks (3 situations to test)
public void AddItem(CartItem item) {
if(item == null)
throw new CartException(Id,"you can not add a null item to the cart");
/* or
throw new CartAddItemNullException();
*/
if(Items.Any(x=>x.Id == item.id))
throw new CartException(Id,"you already have this item in your cart");
/* or
throw new CartAddItemDuplicateException();
*/
if(item.Quantity < 1)
throw new CartException(
Id,string.format(
"the quantity of items added is {0} but should be more than 0",
item.Quantity));
Items.add(item);
}
}
//You already created a specific Exception for your Cart with dedicated information
public class CartException : Exception
{
public int Id {get;set;}
public CartException(int id, string message) :
base(buildMessage(message))
{
Id = id;
}
private string buildMessage(int id, string message)
{
return string.Format(
"Exception on Cart with Id[{0}}",
id,
string.IsNullOrEmpty(message)
? ""
: " : " + message);
}
}
//Then we have here some tests to discuss ;-)
[TestFixture]
public class CartTests
{
// ... obviously other stuff, tests here...
//V1
[Test]
public void can_not_add_null_item_in_the_cart()
{
var sut = new Cart(1);
Check.That(()=>sut.AddItem(null)).Throws<CartException>();
}
//V2
[Test]
public void can_not_add_null_item_in_the_cart()
{
var sut = new Cart(1);
Check.That(()=>sut.AddItem(null))
.Throws<CartException>()
.WithMessage("Exception on Cart with Id[1] : you can not add a null item to the cart");
}
//V3
//we suppose to have here a dedicated exception per test (on which we can test the message somewhere else)
[Test]
public void can_not_add_null_item_in_the_cart()
{
var sut = new Cart(1);
Check.That(()=>sut.AddItem(null))
.Throws<CartAddItemNullException>();
}
@Ouarzy
Copy link

Ouarzy commented Oct 28, 2013

V1 is probably not enough but better that nothing.
V2 seems over verification in many cases, still I could imagine some specific project where it could be usefull. But this is hard to maintain (and what about some messages in others languages?).
V3 is the more OO logic way to manage it for me.

My 2 cents :)

@dupdob
Copy link

dupdob commented Oct 28, 2013

One thing first: don't let current limitation in the nFluent exceptions checks be a limit. I think that check on message should be more flexible.
V2 hints that exception message could be displayed to the ene user. If that's right, to answer Ouaray comment, you need to control the locale you plan to test for. And add other similar tests for other locale, or find a nice testing framework that helps
V3 hints that you except the API integrator to implement special rules for that case.
Choosing is a matter of intents.

My opinion is that your exceptions are for developper, then the null case must NullArgExc for null, invalidopexc for adding twice the same and Invalidargs for the invalid quantity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment