Testing the process of assigning offers to a customer 2
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I asked this question earlier: Testing the process of assigning offers to a customer. Following on from the answerers comprehensive response. I have attempted it again. Please see the test code below:
[TestFixture]
public class CustomerTest
private IList<IProduct> _products;
private Concor _concor;
private Chestnut _chestnut;
private IOfferCalculator _offerCalculator;
[OneTimeSetUp]
public void OneTimeSetUp()
_offerCalculator = new OfferCalculator();
[SetUp]
public void Setup()
_concor = new Concor();
_chestnut = new Chestnut();
_products = new List<IProduct>();
_products.Add(_concor);
_products.Add(_chestnut);
[Test]
public void Should_receive_a_for_concor()
var expectedConcor = new List<IProduct>();
expectedConcor.Add(_concor);
var gender = "F";
var expenditure = 1500M;
var customer = new Customer(gender,expenditure);
//Act
var eligibleProducts = customer.GetEligibleOffers(_offerCalculator, _products);
customer.AssignOffers(eligibleProducts.ToList());
//Assert
CollectionAssert.AreEqual(customer._assignedProducts, expectedConcor);
Here is the supporting code:
public class Concor : IProduct
//Added constants
private const decimal _expenditure =100;
private const string _gender = "F";
public bool IsEligible(string gender, decimal expenditure)
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
public class Chestnut : IProduct
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
private const decimal _expenditure = 100;
private const string _gender = "M";
public bool IsEligible(string gender, decimal expenditure)
//Remove magic string and magic decimal
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
//Replaced abstract class with interface
public interface IProduct
//This method now accepts parameters rather than an object
bool IsEligible(string gender, decimal expenditure);
public interface IOfferCalculator
//Renamed this method.
IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products);
public class Customer
public string Gender get; protected set;
public decimal Expenditure get; protected set;
public IList<IProduct> _assignedProducts = new List<IProduct>();
public Customer(string gender, decimal expenditure)
Gender = gender;
Expenditure = expenditure;
//Added this method as a result of refactoring AssignOffers.
public IEnumerable<IProduct> GetEligibleOffers(IOfferCalculator offerCalculator, IList<IProduct> products)
//Pass Gender and Expenditure instead of this object (Customer).
return offerCalculator.CalculateEligibility(Gender, Expenditure, products);
//Refactored this method.
public void AssignOffers(IList<IProduct> products)
foreach (var product in products)
_assignedProducts.Add(product);
public class OfferCalculator : IOfferCalculator
public IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products)
foreach (var product in products)
if (product.IsEligible(gender,expenditure))
yield return product;
I have included comments to show what I have changed.
I would like some feedback about the quality of the test. The company like to use BDD, however I am conscious that I asserting state rather than behaviour (arguing that I am testing calculations rather than orchestrations). I would also like some feedback about my use of the: OneTimeSetup attribute and Setup attribute. Also How would I test for a Chestnut? Add a new method or use an attribute for the test cases?
c# unit-testing
 |Â
show 5 more comments
up vote
1
down vote
favorite
I asked this question earlier: Testing the process of assigning offers to a customer. Following on from the answerers comprehensive response. I have attempted it again. Please see the test code below:
[TestFixture]
public class CustomerTest
private IList<IProduct> _products;
private Concor _concor;
private Chestnut _chestnut;
private IOfferCalculator _offerCalculator;
[OneTimeSetUp]
public void OneTimeSetUp()
_offerCalculator = new OfferCalculator();
[SetUp]
public void Setup()
_concor = new Concor();
_chestnut = new Chestnut();
_products = new List<IProduct>();
_products.Add(_concor);
_products.Add(_chestnut);
[Test]
public void Should_receive_a_for_concor()
var expectedConcor = new List<IProduct>();
expectedConcor.Add(_concor);
var gender = "F";
var expenditure = 1500M;
var customer = new Customer(gender,expenditure);
//Act
var eligibleProducts = customer.GetEligibleOffers(_offerCalculator, _products);
customer.AssignOffers(eligibleProducts.ToList());
//Assert
CollectionAssert.AreEqual(customer._assignedProducts, expectedConcor);
Here is the supporting code:
public class Concor : IProduct
//Added constants
private const decimal _expenditure =100;
private const string _gender = "F";
public bool IsEligible(string gender, decimal expenditure)
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
public class Chestnut : IProduct
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
private const decimal _expenditure = 100;
private const string _gender = "M";
public bool IsEligible(string gender, decimal expenditure)
//Remove magic string and magic decimal
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
//Replaced abstract class with interface
public interface IProduct
//This method now accepts parameters rather than an object
bool IsEligible(string gender, decimal expenditure);
public interface IOfferCalculator
//Renamed this method.
IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products);
public class Customer
public string Gender get; protected set;
public decimal Expenditure get; protected set;
public IList<IProduct> _assignedProducts = new List<IProduct>();
public Customer(string gender, decimal expenditure)
Gender = gender;
Expenditure = expenditure;
//Added this method as a result of refactoring AssignOffers.
public IEnumerable<IProduct> GetEligibleOffers(IOfferCalculator offerCalculator, IList<IProduct> products)
//Pass Gender and Expenditure instead of this object (Customer).
return offerCalculator.CalculateEligibility(Gender, Expenditure, products);
//Refactored this method.
public void AssignOffers(IList<IProduct> products)
foreach (var product in products)
_assignedProducts.Add(product);
public class OfferCalculator : IOfferCalculator
public IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products)
foreach (var product in products)
if (product.IsEligible(gender,expenditure))
yield return product;
I have included comments to show what I have changed.
I would like some feedback about the quality of the test. The company like to use BDD, however I am conscious that I asserting state rather than behaviour (arguing that I am testing calculations rather than orchestrations). I would also like some feedback about my use of the: OneTimeSetup attribute and Setup attribute. Also How would I test for a Chestnut? Add a new method or use an attribute for the test cases?
c# unit-testing
This looks much better now! ;-) You could put theF
&M
constants in aGenderCode
class and name them accordingly (female/male).
â t3chb0t
Jan 27 at 19:21
Well,100
is a constant now but the name, ouch! The name should explain why it's 100. Is it max or min or some other expenditure? Name it properly.
â t3chb0t
Jan 27 at 19:22
@t3chb0t, if I encapsulate the gender in a immutable GenderCode class then I will have to change the IProduct._gender constant to a read only property. I assume that is what you mean?
â w0051977
Jan 27 at 19:27
It can be either one (const/readonly) - the main point is, it should be as you've said immutable.
â t3chb0t
Jan 27 at 19:29
With regards to the constant names. I will change _expenditure to: _minExpenditure. . I think I will leave Gender as it is?
â w0051977
Jan 27 at 19:33
 |Â
show 5 more comments
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I asked this question earlier: Testing the process of assigning offers to a customer. Following on from the answerers comprehensive response. I have attempted it again. Please see the test code below:
[TestFixture]
public class CustomerTest
private IList<IProduct> _products;
private Concor _concor;
private Chestnut _chestnut;
private IOfferCalculator _offerCalculator;
[OneTimeSetUp]
public void OneTimeSetUp()
_offerCalculator = new OfferCalculator();
[SetUp]
public void Setup()
_concor = new Concor();
_chestnut = new Chestnut();
_products = new List<IProduct>();
_products.Add(_concor);
_products.Add(_chestnut);
[Test]
public void Should_receive_a_for_concor()
var expectedConcor = new List<IProduct>();
expectedConcor.Add(_concor);
var gender = "F";
var expenditure = 1500M;
var customer = new Customer(gender,expenditure);
//Act
var eligibleProducts = customer.GetEligibleOffers(_offerCalculator, _products);
customer.AssignOffers(eligibleProducts.ToList());
//Assert
CollectionAssert.AreEqual(customer._assignedProducts, expectedConcor);
Here is the supporting code:
public class Concor : IProduct
//Added constants
private const decimal _expenditure =100;
private const string _gender = "F";
public bool IsEligible(string gender, decimal expenditure)
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
public class Chestnut : IProduct
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
private const decimal _expenditure = 100;
private const string _gender = "M";
public bool IsEligible(string gender, decimal expenditure)
//Remove magic string and magic decimal
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
//Replaced abstract class with interface
public interface IProduct
//This method now accepts parameters rather than an object
bool IsEligible(string gender, decimal expenditure);
public interface IOfferCalculator
//Renamed this method.
IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products);
public class Customer
public string Gender get; protected set;
public decimal Expenditure get; protected set;
public IList<IProduct> _assignedProducts = new List<IProduct>();
public Customer(string gender, decimal expenditure)
Gender = gender;
Expenditure = expenditure;
//Added this method as a result of refactoring AssignOffers.
public IEnumerable<IProduct> GetEligibleOffers(IOfferCalculator offerCalculator, IList<IProduct> products)
//Pass Gender and Expenditure instead of this object (Customer).
return offerCalculator.CalculateEligibility(Gender, Expenditure, products);
//Refactored this method.
public void AssignOffers(IList<IProduct> products)
foreach (var product in products)
_assignedProducts.Add(product);
public class OfferCalculator : IOfferCalculator
public IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products)
foreach (var product in products)
if (product.IsEligible(gender,expenditure))
yield return product;
I have included comments to show what I have changed.
I would like some feedback about the quality of the test. The company like to use BDD, however I am conscious that I asserting state rather than behaviour (arguing that I am testing calculations rather than orchestrations). I would also like some feedback about my use of the: OneTimeSetup attribute and Setup attribute. Also How would I test for a Chestnut? Add a new method or use an attribute for the test cases?
c# unit-testing
I asked this question earlier: Testing the process of assigning offers to a customer. Following on from the answerers comprehensive response. I have attempted it again. Please see the test code below:
[TestFixture]
public class CustomerTest
private IList<IProduct> _products;
private Concor _concor;
private Chestnut _chestnut;
private IOfferCalculator _offerCalculator;
[OneTimeSetUp]
public void OneTimeSetUp()
_offerCalculator = new OfferCalculator();
[SetUp]
public void Setup()
_concor = new Concor();
_chestnut = new Chestnut();
_products = new List<IProduct>();
_products.Add(_concor);
_products.Add(_chestnut);
[Test]
public void Should_receive_a_for_concor()
var expectedConcor = new List<IProduct>();
expectedConcor.Add(_concor);
var gender = "F";
var expenditure = 1500M;
var customer = new Customer(gender,expenditure);
//Act
var eligibleProducts = customer.GetEligibleOffers(_offerCalculator, _products);
customer.AssignOffers(eligibleProducts.ToList());
//Assert
CollectionAssert.AreEqual(customer._assignedProducts, expectedConcor);
Here is the supporting code:
public class Concor : IProduct
//Added constants
private const decimal _expenditure =100;
private const string _gender = "F";
public bool IsEligible(string gender, decimal expenditure)
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
public class Chestnut : IProduct
//Added constants. Not sure whether they should be private or public. Surely they should be private and not public just so users
//of the Domsain Model can see them?
private const decimal _expenditure = 100;
private const string _gender = "M";
public bool IsEligible(string gender, decimal expenditure)
//Remove magic string and magic decimal
if (expenditure > _expenditure && gender == _gender)
return true;
else
return false;
//Replaced abstract class with interface
public interface IProduct
//This method now accepts parameters rather than an object
bool IsEligible(string gender, decimal expenditure);
public interface IOfferCalculator
//Renamed this method.
IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products);
public class Customer
public string Gender get; protected set;
public decimal Expenditure get; protected set;
public IList<IProduct> _assignedProducts = new List<IProduct>();
public Customer(string gender, decimal expenditure)
Gender = gender;
Expenditure = expenditure;
//Added this method as a result of refactoring AssignOffers.
public IEnumerable<IProduct> GetEligibleOffers(IOfferCalculator offerCalculator, IList<IProduct> products)
//Pass Gender and Expenditure instead of this object (Customer).
return offerCalculator.CalculateEligibility(Gender, Expenditure, products);
//Refactored this method.
public void AssignOffers(IList<IProduct> products)
foreach (var product in products)
_assignedProducts.Add(product);
public class OfferCalculator : IOfferCalculator
public IEnumerable<IProduct> CalculateEligibility(string gender, decimal expenditure, IList<IProduct> products)
foreach (var product in products)
if (product.IsEligible(gender,expenditure))
yield return product;
I have included comments to show what I have changed.
I would like some feedback about the quality of the test. The company like to use BDD, however I am conscious that I asserting state rather than behaviour (arguing that I am testing calculations rather than orchestrations). I would also like some feedback about my use of the: OneTimeSetup attribute and Setup attribute. Also How would I test for a Chestnut? Add a new method or use an attribute for the test cases?
c# unit-testing
asked Jan 27 at 19:18
w0051977
389112
389112
This looks much better now! ;-) You could put theF
&M
constants in aGenderCode
class and name them accordingly (female/male).
â t3chb0t
Jan 27 at 19:21
Well,100
is a constant now but the name, ouch! The name should explain why it's 100. Is it max or min or some other expenditure? Name it properly.
â t3chb0t
Jan 27 at 19:22
@t3chb0t, if I encapsulate the gender in a immutable GenderCode class then I will have to change the IProduct._gender constant to a read only property. I assume that is what you mean?
â w0051977
Jan 27 at 19:27
It can be either one (const/readonly) - the main point is, it should be as you've said immutable.
â t3chb0t
Jan 27 at 19:29
With regards to the constant names. I will change _expenditure to: _minExpenditure. . I think I will leave Gender as it is?
â w0051977
Jan 27 at 19:33
 |Â
show 5 more comments
This looks much better now! ;-) You could put theF
&M
constants in aGenderCode
class and name them accordingly (female/male).
â t3chb0t
Jan 27 at 19:21
Well,100
is a constant now but the name, ouch! The name should explain why it's 100. Is it max or min or some other expenditure? Name it properly.
â t3chb0t
Jan 27 at 19:22
@t3chb0t, if I encapsulate the gender in a immutable GenderCode class then I will have to change the IProduct._gender constant to a read only property. I assume that is what you mean?
â w0051977
Jan 27 at 19:27
It can be either one (const/readonly) - the main point is, it should be as you've said immutable.
â t3chb0t
Jan 27 at 19:29
With regards to the constant names. I will change _expenditure to: _minExpenditure. . I think I will leave Gender as it is?
â w0051977
Jan 27 at 19:33
This looks much better now! ;-) You could put the
F
& M
constants in a GenderCode
class and name them accordingly (female/male).â t3chb0t
Jan 27 at 19:21
This looks much better now! ;-) You could put the
F
& M
constants in a GenderCode
class and name them accordingly (female/male).â t3chb0t
Jan 27 at 19:21
Well,
100
is a constant now but the name, ouch! The name should explain why it's 100. Is it max or min or some other expenditure? Name it properly.â t3chb0t
Jan 27 at 19:22
Well,
100
is a constant now but the name, ouch! The name should explain why it's 100. Is it max or min or some other expenditure? Name it properly.â t3chb0t
Jan 27 at 19:22
@t3chb0t, if I encapsulate the gender in a immutable GenderCode class then I will have to change the IProduct._gender constant to a read only property. I assume that is what you mean?
â w0051977
Jan 27 at 19:27
@t3chb0t, if I encapsulate the gender in a immutable GenderCode class then I will have to change the IProduct._gender constant to a read only property. I assume that is what you mean?
â w0051977
Jan 27 at 19:27
It can be either one (const/readonly) - the main point is, it should be as you've said immutable.
â t3chb0t
Jan 27 at 19:29
It can be either one (const/readonly) - the main point is, it should be as you've said immutable.
â t3chb0t
Jan 27 at 19:29
With regards to the constant names. I will change _expenditure to: _minExpenditure. . I think I will leave Gender as it is?
â w0051977
Jan 27 at 19:33
With regards to the constant names. I will change _expenditure to: _minExpenditure. . I think I will leave Gender as it is?
â w0051977
Jan 27 at 19:33
 |Â
show 5 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186148%2ftesting-the-process-of-assigning-offers-to-a-customer-2%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
This looks much better now! ;-) You could put the
F
&M
constants in aGenderCode
class and name them accordingly (female/male).â t3chb0t
Jan 27 at 19:21
Well,
100
is a constant now but the name, ouch! The name should explain why it's 100. Is it max or min or some other expenditure? Name it properly.â t3chb0t
Jan 27 at 19:22
@t3chb0t, if I encapsulate the gender in a immutable GenderCode class then I will have to change the IProduct._gender constant to a read only property. I assume that is what you mean?
â w0051977
Jan 27 at 19:27
It can be either one (const/readonly) - the main point is, it should be as you've said immutable.
â t3chb0t
Jan 27 at 19:29
With regards to the constant names. I will change _expenditure to: _minExpenditure. . I think I will leave Gender as it is?
â w0051977
Jan 27 at 19:33