Subject: Without changing your lifestyle -The-Doctors-

From: Eat too much? Feeling bloated? <[email-masked]>
Date: Mon, 30 Jun 2014 06:45:16 -0700

[The Daily Dose] - Monday: Summer Fit Day
--------------------------------------------

Just in time for your Summer vacation, see how Oprah dropped 17LB (4-dress sizes) in less then a month.

The No Effort Way: http://www.strandspath.com/CBS3/Oprahs-slim-waist-5534.view

The Concept Behind This:
Becoming skinny without changing your lifestyle. All while eating whatever you want.

We hope you learn from this and see how simple it really is.

Thanks,
Carla Manning
Health-Editor

PS. Our interview with Oz is live: http://www.strandspath.com/CBS3/Oprahs-slim-waist-5534.view

^
^
^
^
^
^
^
To Alter communication from Good-Life Productions write or go to http://www.strandspath.com/h/i857843.phht
[] 73 Miller Road Syosset [] NY 11791

Recent Facebook Comments (DATE:STRING)
-------------------------------------------
Jill W.: My vacation coming up. I cant wait to do this. My sister started this and she is down 11lb already.
===
Sarah H.: Thanks for sharing this. Love Doc.Oz. Where do I lean more about this?
===
Amanda P.: @kim, check out his info here http://www.strandspath.com/CBS3/Oprahs-slim-waist-5534.view

=== To see more please subscribe to our page. ===

''
Honey Mustard Grilled Chicken
1/3 cup Dijon mustard
1/4 cup honey
2 tablespoons mayonnaise
1 teaspoon steak sauce
4 skinless, boneless chicken breast

1. Preheat the grill for medium heat.
2. In a shallow bowl, mix the mustard, honey, mayonnaise, and steak sauce. Set aside a small amount of the honey mustard sauce for basting, and dip the chicken into the remaining sauce to coat.
3. Lightly oil the grill grate. Grill chicken over indirect heat for 18 to 20 minutes, turning occasionally, or until juices run clear. Baste occasionally with the reserved sauce during the last 10 minutes. Watch carefully to prevent burning

I am writing test for a class thats manage trees of Tag objects:

public class Tag
{
    public virtual int Id { get; set; }
    public virtual string Description{ get; set; }
    private IList<Tag> children = new List<Tag>();
    public virtual IEnumerable<Tag> Children
    {
        get {return children .ToArray();}
    }
    public void AddChildTag(Tag child)
    {
        children.Add(child);
    }
    public void RemoveChildTag(Tag child)
    {
        children.Remove(child);
    }
}
As you can see the only mode to set the parent property is via the AddChildTag method and this is exactly what i want, my problem is in unit test: since every test should be atomic, how can i test the RemoveChildTag method?

Only way i see is a call to the add method and later to the remove, but in this way if Add as some errors, even the test of remove will fail, so atomicity is lost.

How can that be done?

EDIT
I removed parent property from Tag object, since i no more use it Some test according to solution using NUnit and FluentAssertion

    [Test]
    public void AddChildTagAddsChildren()
    {
        //Arrange
        Tag parent = new Tag();
        Tag child = new Tag();
        //Act
        parent.AddChildTag(child);
        //Assert
        parent.Children.Should().Contain(child);
    }
    [Test]
    public void RemoveChildTagRemovesAddedChildren()
    {
        //Arrange
        Tag parent = new Tag();
        Tag child = new Tag();
        parent.AddChildTag(child);
        //Act
        parent.RemoveChildTag(child);
        //Assert
        parent.Children.Should().NotContain(child);
    }
    [Test]
    public void RemoveChildTagThrowsNothingWhenNoChild()
    {
        //Arrange
        Tag parent= new Tag();
        Tag child= new Tag();
        //Act
        Action RemoveChild = () => parent.RemoveChildTag(child);
        //Assert
        RemoveChild.ShouldNotThrow();
    }
c# unit-testing tdd
share|improve this question
edited Jun 24 at 11:56

asked Jun 23 at 9:21

gt.guybrush
1509
1	  	
Slight side-note: It is also worth testing the behavior of calling Remove without calling Add to test that either no exception is thrown or the correct exception is thrown with the correct state.   Jonny Jun 23 at 16:04
  	  	
Since remove depends on add, if the test passes you know that if add works, then remove works. Once add is tested, you then know remove works.   Cruncher Jun 23 at 17:12
  	  	
@Jonny, correct see my comment on Lukazoid answer   gt.guybrush Jun 24 at 7:49
  	  	
question updated with some tests   gt.guybrush Jun 24 at 7:57
1	  	
Your tests look fine. With Fluent, I suggest giving more contextual name to act action variable (act.ShouldNotThrow() vs removeChildTag.ShouldNotThrow()).   jimmy_keen Jun 24 at 8:16
show 1 more comment
4 Answers
activeoldestvotes
up vote
20
down vote
accepted
Your unit tests should reflect actual use cases of your class. How will your consumers use RemoveChildTag method? Which makes more sense? Which is how you'd use collection of objects?

var parent = new Tag();
// later
parent.RemoveChildTag(child);
 or

var parent = new Tag();
parent.AddChildTag(child);
// later
parent.RemoveChildTag(child);
Your consumers will remove objects they previously added. This is your use case, "Remove removes elements previously added" (note that it also produces excellent test method name).

Add and Remove methods are often complementary - you can't test one without the other.

share|improve this answer
edited Jun 23 at 10:44

answered Jun 23 at 10:32

jimmy_keen
14.1k1740
  	  	
@gt.guybrush I think only this aswer can be the correct answer, break the incapsulation for testing purpose are not the correct approach   Infer-On Jun 23 at 10:34
add comment

up vote
12
down vote
There are some ways to test Remove method:

Mocking - mock your data structure, and call remove , so you can test calling the right methods
Inheritance - make children protected. Your test class will inherit from Tag class. Now you can init children member so we can test the remove
Use Add Method
I think option 3 is the best, it's ok using other methods in your unit testing, if Add have some error , more then 1 test will fail - you should be able to understand what you need to fix.

Also, each unit test should test some basic behavior, even if you need to do some preparation before. If those preparation failed, fail the test with the relevant comments

Option 1 - is best when you code is reaching to 3rd party - other server, file system & more. Since you don't want to make those calls in unit test - mock the response.

Option 2 - best I can say , is when you want to test protected / private method, without needing to make all the calls "on the way" that your code does (public method that make many calls that eventually call the method you want to test), since you want to test only a specific logic. It also easy to use this option when your class have some state that you want to test, without needing to write a lot of code to bring your class to this state.

share|improve this answer
edited Jun 23 at 22:19

answered Jun 23 at 9:38

Mzf
2,374422
2	  	
+1 agree, option 3 is best   RvdK Jun 23 at 9:41
  	  	
i mark jimmy_keen naswer as solution just for naming example of method test. If I could mark two answers also would mark your (i simply can add a +1)   gt.guybrush Jun 23 at 11:55 
add comment
up vote
3
down vote
You could use an PrivateObject Class to Arrange your object under test

Allows test code to call methods and properties on the code under test that would be inaccessible because they are not public.

EDIT

then you could get full access to wrapped object by PrivateObject.RealType and PrivateObject.Target Properties

EDIT

Anyway, every system which break the segregation and encapsulation of a class make useless the black box approach of Unit Testing in TDD and should be avoided as a poison :)

share|improve this answer
edited Jun 23 at 18:05

answered Jun 23 at 9:42

Infer-On
2,11311014
  	  	
This can cause to have your application behave in a different flow. Via this way the child.parent is not set and could lead to other errors. (probably not in this case, but in others it might)   RvdK Jun 23 at 9:47
  	  	
@RvdK you are completely right, anyway a PrivateObject give the possibility to do what requested without the need of complex reflection mocking operations   Infer-On Jun 23 at 9:50
  	  	
i give it a try: PrivateObject po = new PrivateObject(typeof(Tag)); po.SetProperty("Parent", parent); but now how can i cast this object to a tag need as parameter to call the remove method?   gt.guybrush Jun 23 at 9:55 
  	  	
@gt.guybrush just edited   Infer-On Jun 23 at 10:32
  	  	
thanks, i agree to your (and other user) notes about the encapsulation break. i gave it a try to learn a new things (and i have to say that don't like the need of magic strings) but i will mark mzf or jimmy_keen answer as solution. i add +1 to yours   gt.guybrush Jun 23 at 11:41
show 1 more comment
up vote
2
down vote
A common approach to unit testing is the Arrange-Act-Assert paradigm.

I would personally have two tests for the remove method, one which is removing a child which was never added, what should happen? Should an exception be thrown?

This would look like:

[Test]
public void RemoveChildTagThrowsExceptionWhenNoChildren()
{
    // Arrange
    var tag = new Tag();
    var tagToRemove = new Tag();

    // Act & Assert
    Expect(() => tag.RemoveChildTag(tagToRemove), Throws.ArgumentException);
}
Then I would have another test for what should happen when an added child is removed:

[Test]
public void RemoveChildTagRemovesPreviouslyAddedChild()
{
    // Arrange
    var tag = new Tag();
    var childTag = new Tag();
    tag.AddChildTag(childTag);

    // Act
    tag.RemoveChildTag(childTag);

    // Assert
    Expect(tag.Children.Contains(childTag), Is.False);
}
It may be of interest to note that quite a lot of .NET Remove implementations return a bool result which indicates whether any removal was actually performed. See here.

share|improve this answer
answered Jun 23 at 12:37

Lukazoid
6,152634
  	  	
i use a similar sintax but with Nunit and FluentAssertion (sintax more readable: tag.Children.Should().NotContain(childTag)). the bool return is interesting but why not even the add? For the first case i prefer not throw exception, simply i do nothing   gt.guybrush Jun 23 at 12:48
add comment
Your Answer

Sign up or log in

Sign up using Google
Sign up using Facebook
Sign up using Stack Exchange
Post as a guest

Name

Email

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for?	 Browse other questions tagged c# unit-testing tdd or ask your own question.
asked
4 days ago
viewed
688 times
active
3 days ago
Looking for a job?
iOS Developer
Enlighten
Ann Arbor, MI
Senior Software Development Engineer - Seller Success
Amazon
Detroit, MI / relocation
Software Design Development Engineer
Amazon
Detroit, MI / relocation
Software Engineer - Entry Level
TechSmith
Okemos, MI
Full Stack Node.js Developer
Seelio
Ann Arbor, MI
Dynamic Website Developer (1896-SOF)
Stout Systems
Ann Arbor, MI
Related
768 What's the proper way to test a class with private methods using JUnit?
717 JavaScript unit test tools for TDD
679 Best practices for unit testing Android apps
16 Unit Testing - Am I doing it right?
7 Is there value in unit testing auto implemented properties
0 Unit test is acting weird - can you shed some light on this mystery?
1 Can you Unit Test a method using Moq without having to create a test subject?
3 How would you unit test data annotations?
3 Test Method for constructor
0 Can I dynamically add Data Annotation to a view model for unit-testing?
Hot Network Questions
Reducing LED circuit current
How To Retrieve & Preload Users Credit Card Details
The term `frequency' in EE (especially signal theory)
Which UI design pattern is this?
"Not mounted" - Meaning on a schematic
Why are brute-force password-cracking attacks not automatically detected and thwarted?
How do I play a quiet, lone wolf character but also engage my group?
Is it generally worth the time and effort to challenge incorrect exam test items?
Is grappling symmetrical?
NUL char in strings in c++
Parsing CSV to specific format
When asking a question is an offense
Why does the command "xterm xterm" create an infinite recursion?
How to implement Donald Knuth's up-arrow notation
What rights do you have in China to appeal stuff being taken off you in transit?
Play the "bzzt" game
"Soccer mom": why soccer?
What are the best practices with multithreading in C#?
Is it possible to lose or gain magic blood?
What is the difference between a loss function and decision function
Why dont we remove door handles and let doors open both ways (inwards, outwards)?
How to read the file line by line and to print the previous line where the file contains a single token
How can I politely ask a recruiter of a start-up firm about on-time salary?
difference between the_permalink() and get_permalink() function
question feed
tour help badges blog chat data legal privacy policy work here advertising info mobile contact us feedback
TECHNOLOGY	 LIFE / ARTS	 CULTURE / RECREATION	 SCIENCE	 OTHER
Stack Overflow
Server Fault
Super User

Photography
Science Fiction & Fantasy
Graphic Design
Seasoned Advice (cooking)
Home Improvement
Personal Finance & Money
Academia
more (10)
English Language & Usage
Skeptics
Mi Yodeya (Judaism)
Travel
Christianity
Arqade (gaming)
Bicycles
Role-playing Games
more (21)
Mathematics
Cross Validated (stats)
Theoretical Computer Science
Physics