locked
Should I refactor object passed in as a parameter to use a interface? RRS feed

  • Question

  • I have a class with the method 'InstallConcepts" this method takes a object as a parameter. I want to create some unit tests for this method.

    Should I refactor the parameter on the method to take a interface instead of an object?

    How would I create a single unit test for this method? Any help is appreciated. I'm using

    I have created a unit test below, but I have many questions

    1. how do I know what to put into IConcept? Do I need to look at IConcept?

    2. Do I need to fake out unicornContext, first by replacing it with an interface?

    3. Do I need to replace Dictionary<string, IConcept> with IDictionary?

    4. what do I assert on? I'm not returning anything from this method?

    [TestMethod]
            public void InstallConcepts()
            {
                // Arrange
                // Stub IConcept
                IConcept concept = new Something.Fakes.StubIConcept();
    
                var componentUnderTest = new PlotDefinition(concept, "string", "12345", "something", "string");
    
                // Act
                componentUnderTest.InstallConcepts();
    
                // Assert
                Assert.
            }






    • Edited by witdaj Friday, December 14, 2012 1:26 AM
    Wednesday, November 21, 2012 8:18 PM

Answers

  • I can't tell you what tests to write or what to write in them because I don't know what your components are meant to do. One approach you can try is write test methods that read like Given/When/Then sentences: Given , When <action>, Then <result>. Pre-condition, Action, and Result parts of the sentence become the Arrange, Act and Assert parts of the test.

    For example, I'm guessing that Given a PlotDefinition with Concept set to null, When Dictionary containing a Concept with matching ID is passed to the InstallConcepts method, Then Concept field is initialized with reference from the dictionary. Here is a test that matches this sentence.

    [TestMethod]

    public void InstallConceptsInitializesConceptField() { var target = new PlotDefinition(id = "42"); var concept = new StubIConcept(); var concepts = new Dictionary<string, IConcept> { { "42", concept } }; target.InstallConcepts(concepts);

    Assert.AreSame(concept, target.Concept); }

    1. how do I know what to put into IConcept? Do I need to look at IConcept?
    If it changes results of InstallConcepts method, yes.

    2. Do I need to fake out unicornContext, first by replacing it with an interface?
    No. From standpoint of testing (as opposed to API design), you should replace classes with interfaces only if they introduce significant sideeffects you want to eliminate from your test and you cannot use virtual methods to achieve the same result.

    3. Do I need to replace Dictionary<string, IConcept> with IDictionary?
    That's a good idea because the interface already exists.

    4. what do I assert on? I'm not returning anything from this method?
    Assert on observable state of your components, such as the Concept field of PlotDefinition.



    Wednesday, December 12, 2012 6:26 PM

All replies

  • Hi Chuckdawit,

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Thursday, November 22, 2012 7:58 AM
  • I can't tell you what tests to write or what to write in them because I don't know what your components are meant to do. One approach you can try is write test methods that read like Given/When/Then sentences: Given , When <action>, Then <result>. Pre-condition, Action, and Result parts of the sentence become the Arrange, Act and Assert parts of the test.

    For example, I'm guessing that Given a PlotDefinition with Concept set to null, When Dictionary containing a Concept with matching ID is passed to the InstallConcepts method, Then Concept field is initialized with reference from the dictionary. Here is a test that matches this sentence.

    [TestMethod]

    public void InstallConceptsInitializesConceptField() { var target = new PlotDefinition(id = "42"); var concept = new StubIConcept(); var concepts = new Dictionary<string, IConcept> { { "42", concept } }; target.InstallConcepts(concepts);

    Assert.AreSame(concept, target.Concept); }

    1. how do I know what to put into IConcept? Do I need to look at IConcept?
    If it changes results of InstallConcepts method, yes.

    2. Do I need to fake out unicornContext, first by replacing it with an interface?
    No. From standpoint of testing (as opposed to API design), you should replace classes with interfaces only if they introduce significant sideeffects you want to eliminate from your test and you cannot use virtual methods to achieve the same result.

    3. Do I need to replace Dictionary<string, IConcept> with IDictionary?
    That's a good idea because the interface already exists.

    4. what do I assert on? I'm not returning anything from this method?
    Assert on observable state of your components, such as the Concept field of PlotDefinition.



    Wednesday, December 12, 2012 6:26 PM