Here's a quick example of how I'm testing my wizard steps.
Firstly, I've created a new class which inherits from the GenericBaseWizardStepTest class in UnitTestSupport. This is to provide support for the Castle.Tools.CodeGenerator-generated Site map which I use to do my navigation with now. It also provides support for "spoofing" some validation errors, so I can simulate a DataBind validation failure:
public abstract class BaseWizardStepTest<W, C> : GenericBaseWizardStepTest<W, C> where W : WizardStepPage where C : Controller { protected IArgumentConversionService argumentConversionService; protected ICodeGeneratorServices codeGeneratorServices; protected IControllerReferenceFactory controllerReferenceFactory; protected IDictionaryAdapterFactory dictionaryAdapterFactory; protected IRedirectService redirectService; protected IRuntimeInformationService runtimeInformationService; protected MockRepository mocks; public virtual void SetUp() { mocks = new MockRepository(); argumentConversionService = mocks.PartialMock<DefaultArgumentConversionService>(); controllerReferenceFactory = new MockControllerReferenceFactory(mocks); dictionaryAdapterFactory = mocks.PartialMock<DictionaryAdapterFactory>(); redirectService = mocks.PartialMock<AspDotNetRedirectService>(); runtimeInformationService = mocks.PartialMock<DefaultRuntimeInformationService>(); codeGeneratorServices = mocks.PartialMock<DefaultCodeGeneratorServices>( controllerReferenceFactory, redirectService, argumentConversionService, runtimeInformationService); } protected void InitializeThreadPrincipal(string identity, params string[] roles) { BaseTestHelper.InitializeThreadPrincipal(Context, identity, roles); } protected static void SetValidationErrorsForObject(SmartDispatcherController controllerOrWizardStep, object validatedInstance, params KeyValuePair<string, string>[] errors) { BaseTestHelper.SetValidationErrorsForObject(controllerOrWizardStep, validatedInstance, errors); } protected RootAreaNode Site { get { return new RootAreaNode(codeGeneratorServices); } } protected static string ThreadIdentity { get { return BaseTestHelper.ThreadIdentity; } } }
Then for testing a particular wizard step, we subclass this further:
[TestFixture]
public class GeneralStepTests : BaseWizardStepTest<GeneralStep, WizardController>
{
private IContentRepository contentRepository;
private IGeneralView view;
private IGetProductDetailsService getProductDetailsService;
private IUpdateProductDetailsService updateProductDetailsService;
[SetUp]
public override void SetUp()
{
base.SetUp();
contentRepository = mocks.DynamicMock<IContentRepository>();
getProductDetailsService = mocks.DynamicMock<IGetProductDetailsService>();
updateProductDetailsService = mocks.DynamicMock<IUpdateProductDetailsService>();
controller = new WizardController(codeGeneratorServices);
wizardStep = new GeneralStep(codeGeneratorServices, dictionaryAdapterFactory, contentRepository, getProductDetailsService, updateProductDetailsService);
PrepareController(wizardStep, "", "General", "");
InitializeThreadPrincipal(ThreadIdentity, Roles.Account);
}
[Test]
public void IsPreconditionSatisfied_SessionDoesContainAContentId_UserNotRedirected()
{
Context.Session.Add(SessionKeys.ProductContentId, 44);
mocks.ReplayAll();
Assert.IsTrue(RunIsPreConditionSatisfied());
mocks.VerifyAll();
}
[Test]
public void Process_ValidProductDetailsWithZeroContentId_UpdatesProductDetailsSessionItem()
{
ProductDetails productDetails = new ProductDetails();
productDetails.ContentId = 44;
productDetails.ProductName = "a product name";
productDetails.ReleaseDate = DateTime.Today.AddDays(30);
Context.Session[SessionKeys.ProductContentId] = 0;
Site.ProductsArea.Wizard.Steps.SomeOtherStep().Redirect();
mocks.ReplayAll();
wizardStep.Process(productDetails);
mocks.VerifyAll();
Assert.AreEqual(productDetails, Context.Session[SessionKeys.ProductDetails]);
}
[Test]
public void RenderWizardView_SessionContainsProductDetails_PassesProductDetailsFromSessionToTheView()
{
ProductDetails productDetails = new ProductDetails();
productDetails.ContentId = 99;
Context.Session.Add(SessionKeys.ProductDetails, productDetails);
mocks.ReplayAll();
view = dictionaryAdapterFactory.GetAdapter<IGeneralView>(wizardStep.PropertyBag);
RunRenderWizardView();
mocks.VerifyAll();
Assert.AreEqual(productDetails.ContentId, view.ProductDetails.ContentId);
}
}
