none
How can I set the var IStation s to the parameter IStation toAdd? RRS feed

  • Question

  • TI have to pass test checks that stations can be assigned to a line. The code of the test is:
        public void T1()
        {
          ICity c = CityFactory.CreateCity("Paris");
          ILine l1 = c.AddLine("RER A");
          IStation s1 = c.AddStation("Opera", 0, 0);
          IStation s2 = c.AddStation("Chatelet", 1, 1);
          l1.Stations.Count().Should().Be(0);
          s1.Lines.Count().Should().Be(0);
          s2.Lines.Count().Should().Be(0);
          Action action = (() => l1.AddBefore(null, null));
          action.ShouldThrow<ArgumentException>();
          action = (() => l1.AddBefore(s1, null));
          action.ShouldNotThrow();
          l1.Next(s1).Should().BeNull();
          l1.Previous(s1).Should().BeNull();}
    The code that I have tried pass this test by that I used return s from the method Next in the method toAdd. 
        public void AddBefore(IStation toAdd, IStation before = null)
        {
            l = s;
            if (toAdd == null || s == null)
                throw new ArgumentException();
        }
        public IStation Next(IStation s)
        {
            return s;
        }
        public IStation Previous(IStation s)
        {
            return s;
        }

        

    • Edited by BarbraFleg Monday, December 30, 2019 11:44 AM
    Monday, December 30, 2019 11:06 AM

Answers

  • Thank you for the hints. I run to other test issue with unit test when checking function Next.

            

    My issue start in the test on the line l1.Next(s1).Should().BeNull(); l1.Previous(s1).Should().BeNull();. Could you please help me how to verify the function Next and Previous. Could you point out where I am going wrong?
    The Unit Test

    public void T1_stations_can_be_assigned_to_a_line()
    {
        ILine l1 = c.AddLine("RER A");
        IStation s1 = c.AddStation("Opera", 0, 0);
        IStation s2 = c.AddStation("Chatelet", 1, 1);
        l1.Next(s1).Should().BeNull();
        l1.Previous(s1).Should().BeNull();
        s1.Lines.Count().Should().Be(1);
        s2.Lines.Count().Should().Be(0);
        s1.Lines.Single().Should().BeSameAs(l1);
        action = (() => l1.Next(s2));
        action.ShouldThrow<ArgumentException>();
        action = (() => l1.Previous(s2));
        action.ShouldThrow<ArgumentException>();
        l1.Stations.Single().Should().BeSameAs(s1);
        action = (() => l1.AddBefore(s2, s1));
        action.ShouldNotThrow();
        l1.Stations.Count().Should().Be(2);
        s1.Lines.Count().Should().Be(1);
        s2.Lines.Count().Should().Be(1);
        l1.Next(s2).Should().BeSameAs(s1);
        l1.Previous(s1).Should().BeSameAs(s2);
        l1.Next(s1).Should().BeNull();
        l1.Previous(s2).Should().BeNull();
    }


    The error comes at the line (var index = _stations.IndexOf(s);). My code to pass this test:

    public IStation Next(IStation s)
    {
        s = null;
        var sExist = _stations.Contains(s);
        if (!sExist)
        {
            throw new ArgumentException();
        }
        var index = _stations.IndexOf(s);
        var sLast = index == _stations.Count - 1;
        if (sLast)
        {
            throw new ArgumentException();
        }
        return s;
    }
    public IStation Previous(IStation s)
    {
        s = null;
        var sExist = _stations.Contains(s);
        if (!sExist)
        {
            throw new ArgumentException();
        }
        var index = _stations.IndexOf(s);
        var sLast = index == _stations.Count + 1;
        if (sLast)
        {
            throw new ArgumentException();
        }
        return s;
    }
    public void AddBefore(IStation toAdd, IStation before = null)
    {
    
        if (toAdd == null) throw new ArgumentException();
        ((List<Line>)toAdd.Lines).Add(this);
    
        var index = (before != null) ? _stations.IndexOf(before) : -1;
        if (index > 0)
            _stations.Insert(index, toAdd);
        else
            _stations.Add(toAdd);
    }

    • Marked as answer by BarbraFleg Thursday, January 9, 2020 9:49 AM
    Monday, January 6, 2020 11:48 AM
  • Already resolved
    • Marked as answer by BarbraFleg Thursday, January 9, 2020 9:49 AM
    Wednesday, January 8, 2020 9:22 AM

All replies

  • For an example of using an Interface implemented in a class with an Add method see the following. First look at the Interface then the classes following by usage in two forms and note this can work without forms when changing the structure dependent on the project type. And note the code will not match what you have, its a base to learn from or not.

    https://github.com/karenpayneoregon/BroadcastWinForms/tree/master/BroadcastListener_2


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Monday, December 30, 2019 2:20 PM
    Moderator
  • Your AddBefore logic is missing some important information. You are trying to add an item to an existing list before some other item but you didn't pass that list of items in. Furthermore looking at your test method you're expecting `AddBefore` to be an extension method but it isn't so your test code won't work at all. I'm assuming here you're trying to implement `AddBefore` and not that it is being provided elsewhere.

    //Not tested, nor is this an extension method, just getting your test to pass
    public void AddBefore ( ILine line, IStation toAdd, IStation before = null )
    {
       //Find the existing item, making up logic here but assuming Stations is List<IStation>
       var index = (before != null) ? line.Stations.IndexOf(before) : -1;
       
       if (index > 0)
          line.Stations.Insert(index, toAdd);
       else
          line.Stations.Add(toAdd);
    }
    

    Now you can call this in your test method but, again, it isn't an extension method so you cannot treat it like an instance.

    ILine I1 = c.AddLine("RER A");
    ...
    Action action = () => AddBefore(I1, s1, null);

    Note that tests should test only 1 thing. If you have more than a single assertions you're doing it wrong. For example suppose that passing 2 nulls doesn't fail but passing an instance and null does. Your test case fails but you'll never see the success of the first call. Break these tests up and test only 1 logical thing at a time.

    Your calls to Next and Previous seem odd to me as they aren't doing anything. It appears you're using FluentAssertions or similar to test them but I don't know what you're trying to verify. If you want to verify it was inserted at the right spot then I'd question why as you shouldn't test helper methods you've added to your test cases. The general flow of tests is 

    1) Arrange - set up the object under test, this is where mocking may come in
    2) Act - call the method (or sequence of methods) that you are testing for this very specific test case
    3) Assert - verify the method(s) you just called were successful 


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, December 30, 2019 3:10 PM
    Moderator
  • Thank you for the hints. I run to other test issue with unit test when checking function Next.

            

    My issue start in the test on the line l1.Next(s1).Should().BeNull(); l1.Previous(s1).Should().BeNull();. Could you please help me how to verify the function Next and Previous. Could you point out where I am going wrong?
    The Unit Test

    public void T1_stations_can_be_assigned_to_a_line()
    {
        ILine l1 = c.AddLine("RER A");
        IStation s1 = c.AddStation("Opera", 0, 0);
        IStation s2 = c.AddStation("Chatelet", 1, 1);
        l1.Next(s1).Should().BeNull();
        l1.Previous(s1).Should().BeNull();
        s1.Lines.Count().Should().Be(1);
        s2.Lines.Count().Should().Be(0);
        s1.Lines.Single().Should().BeSameAs(l1);
        action = (() => l1.Next(s2));
        action.ShouldThrow<ArgumentException>();
        action = (() => l1.Previous(s2));
        action.ShouldThrow<ArgumentException>();
        l1.Stations.Single().Should().BeSameAs(s1);
        action = (() => l1.AddBefore(s2, s1));
        action.ShouldNotThrow();
        l1.Stations.Count().Should().Be(2);
        s1.Lines.Count().Should().Be(1);
        s2.Lines.Count().Should().Be(1);
        l1.Next(s2).Should().BeSameAs(s1);
        l1.Previous(s1).Should().BeSameAs(s2);
        l1.Next(s1).Should().BeNull();
        l1.Previous(s2).Should().BeNull();
    }


    The error comes at the line (var index = _stations.IndexOf(s);). My code to pass this test:

    public IStation Next(IStation s)
    {
        s = null;
        var sExist = _stations.Contains(s);
        if (!sExist)
        {
            throw new ArgumentException();
        }
        var index = _stations.IndexOf(s);
        var sLast = index == _stations.Count - 1;
        if (sLast)
        {
            throw new ArgumentException();
        }
        return s;
    }
    public IStation Previous(IStation s)
    {
        s = null;
        var sExist = _stations.Contains(s);
        if (!sExist)
        {
            throw new ArgumentException();
        }
        var index = _stations.IndexOf(s);
        var sLast = index == _stations.Count + 1;
        if (sLast)
        {
            throw new ArgumentException();
        }
        return s;
    }
    public void AddBefore(IStation toAdd, IStation before = null)
    {
    
        if (toAdd == null) throw new ArgumentException();
        ((List<Line>)toAdd.Lines).Add(this);
    
        var index = (before != null) ? _stations.IndexOf(before) : -1;
        if (index > 0)
            _stations.Insert(index, toAdd);
        else
            _stations.Add(toAdd);
    }

    • Marked as answer by BarbraFleg Thursday, January 9, 2020 9:49 AM
    Monday, January 6, 2020 11:48 AM
  • Hi BarbraFleg,

    I noticed that there seems to be some custom classes in your code.

    We cannot test without these information.

    So could you please provide a complete testable code?

    So that we can try to solve your problem better and faster.

    Looking forward to your reply.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, January 7, 2020 9:17 AM
  • Already resolved
    • Marked as answer by BarbraFleg Thursday, January 9, 2020 9:49 AM
    Wednesday, January 8, 2020 9:22 AM
  • Hi BarbraFleg,

    I am glad to hear that.

    If it is possible, could you please publish your solution and mark it as answer? This will greatly help users with similar problems.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, January 9, 2020 5:21 AM