Hans Rudel
Hans Rudel

Reputation: 3611

Unit testing a method which relies on multiple methods

I have a MethodA which calls MethodB in a separate class (one which follows an interface).

MethodB had a StreamReader in it, so I refactored the call to new StreamReader() into a new MethodC (in the same class as MethodB).

In order to test MethodA, i need to mock MethodB, but I also need to be able to test MethodB by mocking MethodC.

(I guess it's become clear I'm a little lost.)

namespace JimBob.CsvImporter.Entity
{

public interface IIOManager
{
    TextReader ReturnReader(string path);

    int GetNumberOfColumnsInFile(string filePath, List<string> errorMessageList);
}


public class IOManager : IIOManager
{
    //MethodC
    public TextReader ReturnReader(string filePath)
    {
        return new StreamReader(filePath);
    }

    //MethodB
    public int GetNumberOfColumnsInFile(string filePath, List<String> errorMessageList)
    {
        int numberOfColumns = 0;
        string lineElements = null;

        try
        {
            using (StreamReader columnReader = (StreamReader)ReturnReader(filePath))
            {
                lineElements = columnReader.ReadLine();
                string[] columns = lineElements.Split(',');
                numberOfColumns = columns.Length;
            }
            return numberOfColumns;
        }
        catch (Exception ex)
        {
            errorMessageList.Add(ex.Message);
            return -1;
        }
    }
}


public class EntityVerification
{

    private IIOManager _iomgr;

    public EntityVerification(IIOManager ioManager)
    {
        this._iomgr = ioManager;
    }

    //MethodA
    public void ValidateNumberOfColumns(
        string filePath, int userSpecifiedColumnCount, 
         List<String> errorMessageList
   )
    {
        int numberOfColumnsInFile = 
            _iomgr.GetNumberOfColumnsInFile(filePath, errorMessageList);

        if (userSpecifiedColumnCount != numberOfColumnsInFile) errorMessageList.Add(
            "Number of columns specified does not match number present in file.");
    }

At present my test is as follows:

    [Test]
    public void GetNumberOfColumnsInFile_ReturnsNumberOfColumns_Returns6()
    {
        Mock<IIOManager> mock = new Mock<IIOManager>();
        mock.Setup(x => x.ReturnReader(It.IsAny<string>())).Returns(
           new StringReader("the,big,fat,dog,ate,cats"));
        EntityVerification testObject = new EntityVerification(mock.Object);
        List<String> errorMessageList = new List<string>();
        int i = testObject.GetNumberOfColumnsInFile("blabla.txt", errorMessageList);
        Assert.AreEqual(i , 6);
    }

But this was for when it was part of the Entity Verification Class.

Am i missing something? Any assistance would be appreciated!

Upvotes: 1

Views: 570

Answers (1)

Kyle Trauberman
Kyle Trauberman

Reputation: 25694

In the test for MethodA, Mock MethodB. In a separate test, Mock MethodC to test MethodB.

The test for MethodA is independent from the test for MethodB, so don't over think this too much.

Upvotes: 1

Related Questions