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
0 votes
Here is our preview of our next version. you can download it here
Feel free to comment on this post or via e-mail.


Main Features
1. New NaturalMocks, return a mock that has default behavior
recorder.ReturnDefaultImplementation()

2. New NarturalMocks Ability to create return values within the record session, you can now do:
using (RecordExpectations recorder = RecorderManager.StartRecording()) 
{ 
  MockedClass.Method (); 
  recorder.Return(new SqlInt32(1)); 
}

3. New, can mock signed internal interfaces (.NET 2.0+)
[assembly: InternalsVisibleTo(MockManager.DynamicMocksAssembly)]

4. New, Generics code sugar. (.NET 2.0+)
import TypeMock.Generics;

Creating Mocks
Mock mock = Mock<TestedClass>.MockNextInstance();
Mock mockAll = Mock<TestedClass>.MockAll();
MockObject<TestedClass> mock = MockObject<TestedClass>.Create();
  TestedClass t = mock.Object;

Finding Mocks
Mock<TestedClass>.IsTypeMocked();
Mock<TestedClass>.GetMockAll();

Generic Methods (Reflective Mocks)
Mock m = Mock<GenMethodClass>.MockNextInstance();
m.AlwaysReturn("GenMethod", 11, Generic.Method<int>());

Check Argument Type
mock.ExpectCall("Method").Args(Check<Boolean>.AreSameType(), Check.IsEqual(10));

Natural Mocks (Mock Object – for interfaces etc,)
TestedClass mocked = MockObject<TestedClass>.CreateObject();
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
   mocked.getVar();
   recorder.Return(10);
}


5. Fixed, save user configuration in user application folder
6. Fixed, Better Message when reflective mocking a non existing method
7. Fixed. Mocking multiple Chained Static Methods using default RepeatAlways
using (RecordExpectations recorder = RecorderManager.StartRecording()) 
{ 
  recorder.DefaultBehavior.RepeatAlways(); 
  MockedClass.Service.foo(); 
  MockedClass.Service.bar(); 
}

8. Fixed. Build Server (run with Nant/MSBuild script) will not halt build to show message box when license is about to expire
9. Fixed. AspNetHostingPermission attributes fail NaturalMocks in .NET 1.1
10. Added "Fast Mode" output to log
11. Support 30 day Evaluation license once per computer.
12. Fixed Failure when mock returns a Generic Type or Types with Generic Parameters that are defined in the parent type.
13. Lower Memory Consumption
asked by scott (32k points)

12 Answers

0 votes
I understand you are trying to keep a common code base for all versions of the .NET framework, but I wouldn't have come up a Mock<T> class just for having static methods that otherwise would belong to MockManager.

So, my proposal on this is:

1. Mock<T> should be an extension of Mock. Something like:

public class Mock<T> : Mock
{
    public new T MockedInstance
    {
        get
        {
            return (T)base.MockedInstance;
        }
    }
}


2. MockManager would be extended to include methods like:

public static Mock<T> Mock<T>();
public static MockObject<T> MockObject<T>();


In my opinion, this would make a much cleaner and intuitive API.

I will take this opportunity to re-propose the implementation of something like:

public class MockScope : IDisposable
{
    public MockScope()
    {
        MockManager.ClearAll();
    }
 
    public void Dispose()
    {
        MockManager.Verify();
    }
}


This would allow to code tests like this:

[TestMethod()]
public void TestMethod1()
{
    using (new MockScope())
    {
        // ...
    }
}


On a side note, the TypeMock.Generics assembly shows up in Visual Studios assembly list in the Add Reference dialog as TypeMock.Helpers. It’s kind of confusing.
answered by paulo.morgado (11k points)
0 votes
I like that idea of MockScope. We always end up doing the Verify in each test and ClearAll in TearDown and it'd be nice to not have that redundant code.

Which is to say, I like the idea of MockScope - but it also implies that I'm substituting one set of redundant lines of code for another.

Just brainstorming here - it might be interesting if TypeMock just knew that pattern, so just by virtue of executing a test it would intercept calls to the test runner at the appropriate points and automatically insert those calls in the appropriate spot. Granted, this may be a little limiting given that I'm sure there are folks who might call ClearAll and Verify multiple times during a single test execution, but, at least in my experience, the 90% case is clear/verify once per test.

Maybe that's an option that could be set in TestFixtureSetUp or something - TypeMock.EnableAutoClearAndVerify() or something.
answered by tillig (6.7k points)
0 votes
Thanks guys.
:arrow: Paulo:
We have rethought the API's and are going to merge the generic API's as you have suggested, it is really much cleaner

:arrow: Travis:
We have already implemented both the Scope and Attributes but they didn't make it into the preview.
Although we have running examples of injecting Verifies in the code, it is a bit too fragile as it depends on private code.
We have implemented [AutoClear] and [AutoVerify] for mbunit and nunit (2.4) although not all runners (TestDriven.NET) support this yet.

Here is what we would like the test to look like:
[TestFixture]
[AutoClear] // make sure that we start each test without mocks
public class MyTest
{
   [Test]
   [AutoVerify] // make sure that we verify the calls
   public void ATest()
   {
   }
}

or
[TestFixture]
[AutoVerify] // make sure that we always verify and clear
public class MyTest
{
   [Test]
   public void ATest()
   {
   }
}

It is possible to AutoVerify with a timeout.

:idea: the [AutoVerify] will only fail if the test didn't fail, otherwise it will just Clear the mock
answered by scott (32k points)
0 votes
I dig the AutoVerify/AutoClear thing. Very cool. I wonder if that would make it easier to inject the verify/clear stuff without the test runner having to know about it.

Can't wait until TestDriven.NET supports it. Good stuff!
answered by tillig (6.7k points)
0 votes
We have implemented [AutoClear] and [AutoVerify] for mbunit and nunit (2.4) although not all runners (TestDriven.NET) support this yet.

Just don't forget Visual Studio support
answered by paulo.morgado (11k points)
0 votes
I found a bug in the generic API.

If you define a set of classes like this:

public abstract class AbstractTestClass
{
    private string value = "unmocked";
    public string Value
    {
        get { return this.value; }
        set { this.value = value; }
    }
}

public class TestClass : AbstractTestClass
{
}


When you create a mock for the TestClass all goes well:

MockObject<TestClass> m1 = MockObject<TestClass>.Create();


But when you tru to mock the abstract class:

MockObject<AbstractTestClass>.Create()


I get this exception:

Test method TestProject1.ProgramFixture.TestMethod4 threw exception: System.InvalidCastException: Unable to cast object of type 'TypeMock.Generic.MockObject`1[MockAbstractTestClass]' to type 'TypeMock.Generic.MockObject`1[TestProject1.AbstractTestClass]'..

at TypeMock.Generic.MockObject`1.Create()
at TestProject1.ProgramFixture.TestMethod4() in C:UsersPauloDocumentsVisual Studio 2005ProjectsUnitTestsConsoleApplication1TestProject1ProgramFixture.cs:line 145


Seems like someone got confused into thinking that 'TypeMock.Generic.MockObject`1[MockAbstractTestClass]' derives from 'TypeMock.Generic.MockObject`1[TestProject1.AbstractTestClass]'.

The Create method should return 'TypeMock.Generic.MockObject`1[TestProject1.AbstractTestClass]' instance where the Object property returns an instance of MockAbstractTestClass.
answered by paulo.morgado (11k points)
0 votes
Thanks for reporting the bug. I will upload a new version with the fix.
I am not sure that we will support mstest (Visual Studio) attributes in the current release.
answered by scott (32k points)
0 votes
I can't hardly wait. :D
answered by paulo.morgado (11k points)
0 votes
:idea: Download Second Preview here

Fixes:
1. TypeMock comes in 2 versions. For .NET 1.1 and .NET 2.0 you might have to rereference your projects to the correct dll. In any case make sure that you DON'T copy the dll locally.

Main Fixs
1. Generics code sugar. (.NET 2.0+)
Creating Mocks
Mock mock = MockManager<TestedClass>.Mock();
Mock mockAll = MockManager.MockAll<TestedClass>();
MockObject<TestedClass> mock = MockManager.MockObject<TestedClass>();
  TestedClass t = mock.Object;

Finding Mocks
MockManager.IsTypeMocked<TestedClass>();
MockManager.GetMockAl<TestedClass>l();

Generic Methods (Reflective Mocks)
Mock m =  MockManager<GenMethodClass>.Mock();
m.AlwaysReturn("GenMethod", 11, Generic.Method<int>());

Check Argument Type
mock.ExpectCall("Method").Args(Check.IsTypeOf<Boolean>(), Check.IsEqual(10));

Natural Mocks (Mock Object – for interfaces etc,)
TestedClass mocked = RecorderManager.CreateMockObject<TestedClass>();
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
   mocked.getVar();
   recorder.Return(10);
}

2. Support Visual Studio Orcas Beta 1.
3. Added MockScope
using (MockScope verifier = new MockScope())
{
   Mock mock = MockManager.Mock<TestedClass>();
   mock.ExpectAndReturn("getVar",5);
}
answered by scott (32k points)
0 votes
The new API looks great!

Fixes:
1. Why CAN'T I copy the dll locally?

Main Fixes:
1. I'm sure you meant:

Creating Mocks
Mock<TestedClass> mock = MockManager.Mock<TestedClass>(); 
Mock<TestedClass> mockAll = MockManager.MockAll<TestedClass>(); 
MockObject<TestedClass> mock = MockManager.MockObject<TestedClass>(); 
  TestedClass t = mock.Object;


Generic Methods (Reflective Mocks)
Mock<GenMethodClass> m =  MockManager.Mock<GenMethodClass>(); 
m.AlwaysReturn("GenMethod", 11, Generic.Method<int>());


Right?

3. Thank you!

I have a few questions:

1. If AbstractTestClass is an abstract class
MockObject<AbstractTestClass> m2 = MockManager.MockObject<AbstractTestClass>();
Assert.AreEqual("unmocked", m2.Object.Value);

throws an exception:
Test method TestProject1.ProgramFixture.TestMethod4 threw exception: TypeMock.VerifyException:
TypeMock Verification: Unexpected Call to TestProject1.AbstractTestClass.get_Value().

even is AbstractTestClass has an implementation for Value

2. (this one probably doesn't belong here) what is the difference between calling MockManager.MockObject() and calling RecorderManager.CreateMockedObject(), apart from the return types, of course?
answered by paulo.morgado (11k points)
...