Search This Blog

Loading...

Thursday, July 23, 2009

Use DoInstead for Parameter Verification in Typemock

Typemock AAA syntax is very helpful in mocking out calls. However one of the limitation is that it's not possible to verify the correctness of method parameters.

With the DoInstead API, there is finally a way to verify method parameters. Here's how you can do it.

Assume that you have a word application, and you need to implement save, load file operation. For simplicity's sake you are saving it in XML. Here's your code:
public enum FileOpState
    {
        Saved,
        NotSaved
    }
    public class FileOperationCommand<t>
        where T: class 
    {
        public string PrjPath
        { get; private set; }
      
        public T New()
        {
            return Activator.CreateInstance<t>();
        }

        public T Load()
        {

            PrjPath = GetPrjPath(new OpenFileDialog());

            if (string.IsNullOrEmpty(PrjPath))
                return null;
            using (FileStream fs = new FileStream(PrjPath, FileMode.Open, FileAccess.Read))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(fs);     
            }
        }

        public FileOpState Save(T objectToSave)
        {
            PrjPath = GetPrjPath(new SaveFileDialog());
            
            if (string.IsNullOrEmpty(PrjPath))
                return FileOpState.NotSaved;
            using (TextWriter writeFilStream = new StreamWriter(PrjPath))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                serializer.Serialize(writeFilStream, objectToSave);
                return FileOpState.Saved;            
            } 

        }


        private static string GetPrjPath(FileDialog passInDialog)
        {
            FileDialog fbd = passInDialog;

            fbd.DefaultExt = ".xml";
            fbd.Filter = "XML (*.xml)|*.xml";
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                return fbd.FileName;

            }

            return "";
        }
    }

And you want to test, for this simple application, whether when you call the Save command, the correct dialog box is called. i.e., the FileDialog that you pass into GetPrjPath is SaveFileDialog, not other dialog.

This means that you have to make sure that mock away the GetPrjPath by returning a predefined path, and verify that the passInDialog is of the type SaveFileDialog.

Here's how you can write the code:

[Test, Isolated]
        public void Save_With_Correct_File_Dialog()
        {
            object fileDialogType = null;
            Isolate.NonPublic.WhenCalled(command.GetType(), "GetPrjPath")
            .DoInstead(context=>
                           {
                               fileDialogType = context.Parameters[0];
                               return
                                   @"C:\me.xml";
                           });

            UserInformation userInformation = new UserInformation()
            {
                Age = 10,
                Name = "asef"
            };
            Assert.AreEqual(FileOpState.Saved, command.Save(userInformation));
         Assert.IsInstanceOf<savefiledialog>(fileDialogType);
     
            
        }

See what we do here. First, we use DoInstead to intercept the GetPrjPath method. This ensures that whenever GetPrjPath is called, the code body inside DoInstead steps in. When that happens, we assign the first parameter of the method to an object called fileDialogType, and we return a value for that method. The return value is just to make sure that the code, after exiting from the method body, can continue to run. At the assert part, we make sure that fileDialogType is of the correct type.

That's it!

No comments: