chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
I'm using TypeMock for the first time, so please slap me if I'm doing something I'm not supposed to do.

As tacky as it sounds, I've written a class that executes a command. Yes, I have to execute the command. I'm using System.Diagnostics.Process to do it. However, during UnitTest, I do not want the command to actually be executed (because it may not reside on the machine). I don't want my unit tests to fail simply because the machine they are being run on doesn't have this command installed.

So in comes TypeMock. I want to Mock the Process.Start() method such that it allows me to setup the Process object, but doesn't ever really start it.

And so.. here is my simplified code. I'm using notepad as an example app, it's not the command I'm actually trying to execute.

        public void Exec()
        {
            Process p = new Process();
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.StartInfo.FileName = "notepad";
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.UseShellExecute = false;
            p.Start();
            p.WaitForExit();
        }


And here is my TypeMock-based UnitTest (minus all the MS fluff) method:
        [TestInitialize()]
        public void MyTestInitialize()
        {
            MockManager.Init();
            processMock = MockManager.Mock(typeof(System.Diagnostics.Process));
            MockManager.LogFile = true;

            processMock.Strict = false;
            //processMock.ExpectCall("Start");
            //processMock.ExpectCallAndVerify("Start");
            // Uncomment the next two lines to use strict mode..
            //processMock.Strict = true;
            //processMock.ExpectGetAlways("StartInfo", new ProcessStartInfo());
            processMock.AlwaysReturn("Start", null as Process);
        }

        [TestMethod()]
        public void ExecTest()
        {
            Execute target = new Execute();

            target.Exec();

            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }


ExpectCall("Start") throws an exception because Start doesn't return a void, it returns itself (an instance of Process). I happen to not care about the return in my method, so I can return null (question on that later...).

So if I do this.. notepad runs anyway. As if the Start() method is not being mocked.

I tried using strict and Mocked the constructor and StartInfo properties just fine. If I remove the mocking of Start, I get an except from TypeMock stating that there was an unexpected call to System.Diagnostics.Process.Start(). If I add the AlwaysReturn("Start", null as Process), I still get that error message.

Why is TypeMock ignoring me?

Here is the actual exception that I get when executing this UnitTest..

Test method TestProject1.ExecuteTest.ExecTest threw exception: TypeMock.VerifyException:
TypeMock Verification: Unexpected Call to System.Diagnostics.Process.Start().


Again that's when I use the strict mode. Can anyone show me what I am doing wrong?

Another question.. Should I care about the return code from Start, how would I tell TypeMock to return the mocked object instance as a System.Diagnostics.Process type? I can't seem to cast a MockObject into a Process object...

Thanks!

-Eric
________
NO2 VAPORIZER REVIEWS
asked by erichorne (3.4k points)

8 Answers

0 votes
Hi Eric

Intersesting.
we are looking into your problem.
I'll post the answers as soon as we'll have it. :roll:
answered by ohad (35.4k points)
0 votes
Eric

I'm not sure if that what you mean.
You can try the following:

        [TestMethod()]
        public void ExecTest()
        {
            MockManager.Init();
            Mock processMock = MockManager.Mock(typeof(Execute));
            processMock.ExpectCall("Exec");
            Execute target = new Execute();
            target.Exec();
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }


This will cause Exec method to run without running the process.
I hope that I undersrtand your meaning.
Please give me your feedback.
answered by ohad (35.4k points)
0 votes
Guess i'm not familiar with the Execute type in C#. What namespace would that be found under?

In anycase, the problem was with System.Diagnostics.Process. I need to be able to Mock this class so that I can simulate failures that wouldn't otherwise occur.

For example, I'd like to Mock Process.HasExited so that I can return fake the program into thinking the mock process hasn't exited.

The big problem I have right now is that I can not seem to get TypeMock to Mock the Process.Start() method. In strict mode, it complains about catching the Start method call whether or not I have set an expectation for that call. Outside strict mode, with an expectation set, Process.Start is not caught by TypeMock and really executes the command.

So I need TypeMock to mock Process.Start() so that it pretends like it is executing the command, but doesn't really execute the command.

Thanks

-Eric
________
Expert insurance
answered by erichorne (3.4k points)
0 votes
OK.

I think you are confusing the static Start method that returns process instance and the Start method that returns bool
Notice the ExpectAndReturn statement below.

So Here it is:

        [TestMethod()]
        public void ExecTest()
        {
            MockManager.Init();
            Mock mock = MockManager.Mock(typeof(Process));
            mock.ExpectAndReturn("Start", true);
            Process p = new Process();
            p.Start();
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }


By the way if you would use Natural Mocks none of this would have happened
Hope it answer your question.
answered by ohad (35.4k points)
0 votes
Eric,
Tip: :idea: Run the TypeMock Tracer before running your test will help you find these problems.
Try it with you code and you will see that the exceptation is set on the static while the call is done on an instance.
answered by scott (32k points)
0 votes
Ok, I guess I'm not making myself clear :(

I am trying to test my Execute.Exec method. So I can't mock that method because that's the method I'm trying to test! Inside Execute.Exec, I use the Process class. So it's the Process class I want to mock.

Now, if I mock the Process.Start() method (BTW, you were right, I was confusing the static and non-static methods) like you do in your example, it does not get mocked.

I took Scott's advice about running the tracer. I ran the tracer. It claims the System.Diagnostics.Process.Start is called AND that it is an unmocked call. Under Initialization 0/System.Diagnostics.Process/Instance 0 -- it lists "Start (0/1)". Under Initialization 0/System.Diagnostics.Process/Unmocked Instance 1 it lists "Start (1)".

It would seem that TypeMock is ignoring my ExpectAndReturn("Start",true) expectation.

When you ran this, did notepad not start up during the test? Is this possibly a configuration issue?

The bottomline is, I can't have the Process.Start() function actually execute the command during the test. It needs to be mocked and I can't convince TypeMock to mock it.

Also, I'm not sure I understand how to tell a static call from a non-static call in the tracer.. they both look identical to me.

Thanks for the help!

-Eric
________
List Of Yamaha Products Specifications
answered by erichorne (3.4k points)
0 votes
The confusion with the static Start and the non-Static start was the cause of this problem.

In the course of trying different things, I had make my mock object a "MockObject" type and not a "Mock" type. When I changed it back to a "Mock" type, Start was successfully mocked.

Thanks for all the help!

-Eric
________
Jaguar Mark VII
answered by erichorne (3.4k points)
0 votes
Hi Eric
I'm glad we could help 8)

About the tracer:
Static methods are marked with the 's' letter near the icon on the left on the type view.
You can look here for a better understanding of the tracer output.
answered by ohad (35.4k points)
...