Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

C# Unit Testing in C# What To Test Isolation Testing

Przemysław Hawryluk
Przemysław Hawryluk
14,267 Points

How to write a test to extended treehousedefense code

I have a test:

[Fact]
public void FireOnInvadersDecreasesInvadersHealth()
{
    var map = new Map(3, 3);
    var target = new TowerMock(new MapLocation(0, 0, map));

    var invaders = new InvaderMock[]
    {
        new InvaderMock() {Location = new MapLocation(0, 0, map)},
        new InvaderMock() {Location = new MapLocation(0, 0, map)}
    };
    target.FireOnInvaders(invaders);

    Assert.All(invaders , i => Assert.Equal(1, i.Health));
}

and this fails, because i have extended Tower class, specifically FireOnInvaders methods:

public void FireOnInvaders(IInvader[] invaders)
{
    foreach (IInvader invader in invaders)
    {
        if (invader.IsActive && _location.InRangeOf(invader.Location, Range))
        {
            if (IsSuccessfulShot())
            {
                invader.DecreaseHealth(Power);

                if (invader.IsNeutralized)
                {
                    Console.WriteLine("Neutralized an invader at " + invader.Location + "!");
                }
            }
            else
            {
                Console.WriteLine("Shot at and missed an invader.");
            }
            break;
        }
    }
}

In test IsSuccessfulShot method always gives false by what invaders doesn't lost health, how can I fix it? How can I assume that IsSuccessfulShot will be always true?

6 Answers

Przemysław Hawryluk
Przemysław Hawryluk
14,267 Points

Break statement at the end of FireOnInvaders method, only first invader got 1 damage

James Churchill
James Churchill
Treehouse Teacher

Great job sticking with it and figuring out the problem!

Thanks ~James

James Churchill
STAFF
James Churchill
Treehouse Teacher

Przemysław,

Can you post your implementation for your Tower and TowerMock classes?

Thanks ~James

Przemysław Hawryluk
Przemysław Hawryluk
14,267 Points

Tower class:

public class Tower
    {
        protected virtual int Range { get; } = 1;
        protected virtual int Power { get; } = 1;
        protected virtual double Accuracy { get; } = .75;

        private MapLocation _location;

        public Tower(MapLocation location)
        {
            _location = location;
        }

        public virtual bool IsSuccessfulShot()
        {
            return Random.NextDouble() < Accuracy;
        }

        public void FireOnInvaders(IInvader[] invaders)
        {
            foreach (IInvader invader in invaders)
            {
                if (invader.IsActive && _location.InRangeOf(invader.Location, Range))
                {
                    if (IsSuccessfulShot())
                    {
                        invader.DecreaseHealth(Power);

                        if (invader.IsNeutralized)
                        {
                            Console.WriteLine("Neutralized an invader at " + invader.Location + "!");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Shot at and missed an invader.");
                    }
                    break;
                }
            }
        }
    }

And TowerMock

class TowerMock : Tower
    {
        public override bool IsSuccessfulShot() => true;

        public TowerMock(MapLocation location) : base(location)
        {
        }
    }
James Churchill
STAFF
James Churchill
Treehouse Teacher

Przemysław,

Your TowerMock class looks correct to me. Is your unit test still not working as you expect it to?

Thanks ~James

Przemysław Hawryluk
Przemysław Hawryluk
14,267 Points

Test console

[xUnit.net 00:00:00.1362998] Starting: TreehouseDefense.Tests

[xUnit.net 00:00:00.3022246] TreehouseDefense.Tests.TowerTests.FireOnInvadersDecreasesInvadersHealth [FAIL]

[xUnit.net 00:00:00.3044872] Assert.All() Failure: 1 out of 2 items in the collection did not pass.

[xUnit.net 00:00:00.3049828] [1]: Item: TreehouseDefense.Tests.Mocks.InvaderMock

[xUnit.net 00:00:00.3053321] Xunit.Sdk.EqualException: Assert.Equal() Failure

[xUnit.net 00:00:00.3056650] Expected: 1

[xUnit.net 00:00:00.3059837] Actual: 2

[xUnit.net 00:00:00.3063206] w Xunit.Assert.Equal[T](T expected, T actual, IEqualityComparer`1 comparer)

[xUnit.net 00:00:00.3066321] w Xunit.Assert.Equal[T](T expected, T actual)

[xUnit.net 00:00:00.3069677] w TreehouseDefense.Tests.TowerTests.<>c. <FireOnInvadersDecreasesInvadersHealth>b__0_0(InvaderMock i) w D:\Projekty C#\C-Sharp Objects\C-Sharp ObjectsTests\TowerTests.cs:wiersz 21 [xUnit.net 00:00:00.3072997] w Xunit.Assert.All[T](IEnumerable1 collection, Action1 action)

[xUnit.net 00:00:00.3083268] Stack Trace: [xUnit.net 00:00:00.3088077] w Xunit.Assert.All[T](IEnumerable1 collection, Action1 action) [xUnit.net 00:00:00.3091175] w TreehouseDefense.Tests.TowerTests.FireOnInvadersDecreasesInvadersHealth() w D:\Projekty C#\C-Sharp Objects\C-Sharp ObjectsTests\TowerTests.cs:wiersz 21 [xUnit.net 00:00:00.3229712] Finished: TreehouseDefense.Tests

James Churchill
James Churchill
Treehouse Teacher

Przemysław,

I'd try debugging into your unit test and stepping through the FireOnInvaders method in order to see why the invader's health isn't being decreased. I suspect that it's something other than the IsSuccessfulShot method returning false.

Thanks ~James