jeudi 1 janvier 2015

State design pattern modifying context class collection - How to unit test.

I am currently using nSubstitute and nUnit to do some unit testing. I a newbie when it comes to this stuff so any help would be greatly appreciated. Please have a look at this code:



public class Event
{
private ISet<Host> hostSet;
private IEventState eventState;

public Event()
{
hostSet = new HashSet<Host>();
eventState = new StartedEvent();
}

public virtual string Name { get; protected internal set; }

public virtual bool CanSetName()
{
return eventState.CanSetName();
}

public virtual void SetName(string name)
{
eventState.SetName(this, name);
}

internal virtual ISet<Host> HostSet
{
get
{
return hostSet;
}
}

public virtual ReadOnlyCollection<Host> HostCollection
{
get
{
return new ReadOnlyCollection<Host>(hostSet.ToList());
}
}

public virtual bool CanAddHost()
{
return eventState.CanAddHost();
}

public virtual void AddHost(string firstName, string lastName)
{
eventState.AddHost(this, firstName, lastName);
}

internal virtual void ChangeState(IEventState eventState)
{
this.eventState = eventState;
}

}

public class Host
{
private readonly string firstName;
private readonly string lastName;

public Host(string firstName, string lastname)
{
this.firstName = firstName;
this.lastName = lastname;
}

public string FirstName
{
get
{
return firstName;
}
}

public string LastName
{
get
{
return lastName;
}
}
}

public interface IEventState
{
bool CanSetName();
void SetName(Event evnt, string Name);
bool CanAddHost();
void AddHost(Event evnt, string firstName, string lastName);
}

internal class StartedEvent : IEventState
{

public bool CanSetName()
{
return true;
}

public void SetName(Event evnt, string name)
{
evnt.Name = name;
}

public bool CanAddHost()
{
return true;
}

public void AddHost(Event evnt, string firstName, string lastName)
{
evnt.HostSet.Add(new Host(firstName, lastname));
}
}

[TestFixture]
public class StartedEventState
{
[Test]
public void CanSetName_Always_ReturnsTrue()
{
IEventState eventState = new StartedEvent();
bool result = eventState.CanSetName();
Assert.True(result);
}

[Test]
public void SetName_WhenCalled_ChangesTheEventName()
{
Event evnt = Substitute.For<Event>();
IEventState eventState = new StartedEvent();
eventState.SetName(evnt, "Test Event");
evnt.Received().Name = "Test Event";
}

[Test]
public void CanAddHost_Always_ReturnsTrue()
{
IEventState eventState = new StartedEvent();

bool result = eventState.CanAddHost();

Assert.True(result);
}

[Test]
public void AddHost_WhenCalled_AddsTheHostToTheEvent()
{
//No idea how to test this?
}
}

[TestFixture]
public class EventTests
{
[Test]
public void CanSetName_WhenCalled_DelegatesToItsCurrentState()
{
Event evnt = new Event();
var eventState = Substitute.For<IEventState>();
evnt.ChangeState(eventState);
evnt.CanSetName();
evnt.Received().CanSetName();
}
}


The tests that are currently written all pass. However I have no idea how to perform a test to ensure that the StartedEvent.AddHost method is correctly calling the context class and adding it to the set. I have tried a few different things but have failed miserably.


1) Can someone point me in the right direction as to how I go about testing this method. 2) It would be good if someone could confirm my existing tests are OK.


Aucun commentaire:

Enregistrer un commentaire