I am writing unit tests for my presentation class in MVP pattern.But I am having trouble to write mock setup code.
I have a presenter and when presenter's Load method called I want to test view should load class properties, table fields, data types,set presenter.... So When I have a different thing to do when presenter load always I have to add new expectation to test. And test is getting bigger every time.
[Test]
public void When_Presenter_Loads_View_Should_Display_Selected_Class_Properties()
{
IList<string> dataTypes =new List<string>();
IClassGenerationView view = mockRepository.StrictMock<IClassGenerationView>();
tableRepository = mockRepository.Stub<ITableRepository>();
using(mockRepository.Record())
{
SetupResult.For(tableRepository.GetDataTypes()).Return(dataTypes);
view.Presenter = null;
LastCall.IgnoreArguments();
view.DataTypes = dataTypes;
view.Show();
view.ClassProperties = classProperties;
view.TableName = "Table";
view.Table = table;
LastCall.IgnoreArguments();
}
using(mockRepository.Playback())
{
ClassGenerationPresenter presenter = new ClassGenerationPresenter(view, clazz, tableRepository);
presenter.Load();
}
}
Is there a code smell in this code? How Can I improve or simplify this?
After a long sleepless night and research I have found this solution.When I thougt carefully I have came up with this. I am testing too many behaviour in one test. And I have changed the tests like this
[TestFixture]
public class When_Presenter_Loads
{
private MockRepository mockRepository;
private ITableRepository tableRepository;
private IClass clazz;
private Dictionary<string, Type> properties;
private IClassGenerationView view;
private ClassGenerationPresenter presenter;
[SetUp]
public void Setup()
{
mockRepository =new MockRepository();
properties = new Dictionary<string, Type>();
clazz = mockRepository.DynamicMock<IClass>();
view = mockRepository.DynamicMock<IClassGenerationView>();
tableRepository = mockRepository.Stub<ITableRepository>();
}
[Test]
public void View_Should_Display_Class_Properties()
{
using(mockRepository.Record())
{
SetupResult.For(clazz.Properties).Return(properties);
view.ClassProperties = properties;
}
using(mockRepository.Playback())
{
presenter = new ClassGenerationPresenter(view, clazz, tableRepository);
presenter.Load();
}
}
[Test]
public void View_Should_Display_Class_Name_As_A_Table_Name()
{
using (mockRepository.Record())
{
SetupResult.For(clazz.Name).Return("ClassName");
view.TableName = "ClassName";
}
using (mockRepository.Playback())
{
presenter = new ClassGenerationPresenter(view, clazz, tableRepository);
presenter.Load();
}
}
[Test]
public void View_Should_Display_SQL_Data_Types()
{
List<string> dataTypes = new List<string>();
using(mockRepository.Record())
{
SetupResult.For(tableRepository.GetDataTypes()).Return(dataTypes);
view.DataTypes = dataTypes;
}
using(mockRepository.Playback())
{
presenter = new ClassGenerationPresenter(view, clazz, tableRepository);
presenter.Load();
}
}
[Test]
public void View_Should_Show_Table()
{
using (mockRepository.Record())
{
SetupResult.For(clazz.Name).Return("ClassName");
view.Table = null;
LastCall.IgnoreArguments();
}
using (mockRepository.Playback())
{
presenter = new ClassGenerationPresenter(view, clazz, tableRepository);
presenter.Load();
}
}
}
I have used lots of Dynamic mock to test one behaviour at time. Also you can read Dave's One Mock Per Test article about this