Need Help, thanks.

62 views
Skip to first unread message

Kenny

unread,
May 22, 2012, 11:51:15 PM5/22/12
to Rhino.Mocks
Hi all,
I am new to Rhinomock. We are using C++/CLI, and we want to add
Rhinomock to our unit test framework which builds in VS2008
professional version. The tested Rhinomock version is 3.6 which
supports C++/CLI. I created a C++/CLI unit test project of VS2008 as
following, it can be built successfully. But when run the test method,
it will throw an exception “..., System.InvalidOperationException:
Invalid call, the last call has been used or no call has been made
(make sure that you are calling a virtual (C#) / Overridable (VB)
method)..” I searched on the web, and found people says this exception
is usually for the tested function is non-virtual, but here it's a
virtual one. At the same time, I create a C# unit test project of
VS2008 with the similar code, and it could run successfully. I find it
will be failed in C++/CLI project if I use "LastCall::Return" or
"Expect::Call", throwing the same exception previous.

/***************************** C++/CLI project code
*************************/
/****Successfully built, throw exception when run the test
method.*****/

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;
using namespace Rhino::Mocks;

namespace RhinoMock_Auto
{
template <class T> ref class Using
{
private:
T^ m_Handle;

public:
Using(T^ Object)
{
m_Handle = Object;
}

T^ operator->()
{
return m_Handle;
}

~Using()
{
delete m_Handle;
}
};

public interface class IGetResults
{
public:
virtual int GetSomeNumber(String^ data);
};

[TestClass]
public ref class UnitTest1
{
private:
TestContext^ testContextInstance;
public:
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
property
Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^
TestContext
{
Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ get()
{
return testContextInstance;
}
System::Void
set(Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^
value)
{
testContextInstance = value;
}
};

#pragma region Additional test attributes
//
//You can use the following additional attributes as you write your
tests:
//
//Use ClassInitialize to run code before running the first test in
the class
//[ClassInitialize()]
//static void MyClassInitialize(TestContext^ testContext) {};
//
//Use ClassCleanup to run code after all tests in a class have run
//[ClassCleanup()]
//static void MyClassCleanup() {};
//
//Use TestInitialize to run code before running each test
//[TestInitialize()]
//void MyTestInitialize() {};
//
//Use TestCleanup to run code after each test has run
//[TestCleanup()]
//void MyTestCleanup() {};
//
#pragma endregion

[TestMethod]
void ReturnResultFromMock()
{
MockRepository^ mocks = gcnew MockRepository();
IGetResults^ resultGetter = mocks->Stub<IGetResults^>();
{

Using<IDisposable>(mocks->Record());
resultGetter->GetSomeNumber("a");
LastCall::Return(1); // throw exception at this line
}
int result = resultGetter->GetSomeNumber("a");
Assert::AreEqual(1,result);
}
};
}


/************************** C# project code
**************************/
/***************** Successfully run the test method***************/

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;

namespace TestProject1
{
public interface IGetRestuls
{
int GetSomeNumber(string someInput);
}
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class UnitTest1
{
public UnitTest1()
{
//
// TODO: Add constructor logic here
//
}

private TestContext testContextInstance;

/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test
run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}

#region Additional test attributes
//
// You can use the following additional attributes as you
write your tests:
//
// Use ClassInitialize to run code before running the first
test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext
testContext) { }
//
// Use ClassCleanup to run code after all tests in a class
have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion

[TestMethod]
public void ReturnResultsFromMock()
{
MockRepository repository = new MockRepository();
IGetRestuls resultGetter = repository.Stub<IGetRestuls>();
using (repository.Record())
{

resultGetter.GetSomeNumber("a");
LastCall.Return(1);
}
int result = resultGetter.GetSomeNumber("a");
Assert.AreEqual(1, result);
}
}
}

And my environment is XP with SP3, and VS2008 Professional with SP1.
So, my questions are:
(1) are there some errors in the above C++/CLI project? If have, how
to modify them, thanks.

(2) If it's the Rhinomock own bug, how to workaround it or when it
will be fixed. I saw Rhinomock has a commercial version. Does this
version has this problem too, or is it well to support C++/CLI than
the open source version? Thanks.

(3) I find there are nearly no C++/CLI examples provided by Rhinomock,
does anyone can provided some. Thanks.

(4) For C++/CLI doesn't support lambda, some syntax and other mock
framework(like Typemock) can't be used. Is there other mock framework
well to support C++/CLI? Thanks.

haifisch

unread,
May 23, 2012, 2:53:50 AM5/23/12
to rhino...@googlegroups.com
Hi Kenny,

without a deeper look at your problem I would advice you to restate your test with RhinoMocks-AAA-syntax.

This might look like:

            IGetRestuls resultGetter = MockRepository .GenerateStub<IGetRestuls>()
 resultGetter.Stub(x=>x.GetSomeNumber("a")).Returns(1);
int result = resultGetter.GetSomeNumber("a");
Assert.AreEqual(1, result);
I just wrote that down here in the editor so it might contain some bugs - but the intention should be clear.

In general AAA syntax is easier to read/write and maintain.

Br,

Andreas

纪坤

unread,
May 23, 2012, 3:56:34 AM5/23/12
to rhino...@googlegroups.com
Hi Andreas,
Thank you for your reply. The A-A-A syntax in Rhinomock is supported by lambda syntax. Unfortunately, the C++/CLI doesn't support the lambda syntax. So the provided sentences will not work for C++/CLI. But I saw that C#2.0 without lambda can even use AAA from http://ayende.com/wiki/Rhino%20Mocks%203.5.ashx#UsingtheAAAsyntaxinCCA.
I am trying to translate it into C++/CLI, checking whether it is workable for C++/CLI. But the syntax isn't as nice. And I still wonder why LastCall::Return or Expect::Call can't be used in C++/CLI, or what's wrong in my posted C++/CLI code. Thanks a lot.

Best Regards,

Kenny


2012/5/23 haifisch <andreas...@googlemail.com>
--
You received this message because you are subscribed to the Google Groups "Rhino.Mocks" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rhinomocks/-/zpN333v2utAJ.
To post to this group, send email to rhino...@googlegroups.com.
To unsubscribe from this group, send email to rhinomocks+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rhinomocks?hl=en.

Reply all
Reply to author
Forward
0 new messages