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
I have a test over my "Data Access Layer" code where I want to mock database access to return hardcoded DataSet results. I was getting a strange error, that I can now repeat in a small example code set.

Tester
using NUnit.Framework;
using TypeMock;
namespace TMDataSetProblem
{
   [TestFixture] public class Tester
   {
      [SetUp] public void Start()
      {
         MockManager.Init();
      }

      [TearDown] public void Finish()
      {
         MockManager.Verify();
      }


      [Test]
      public void DataSetProblem()
      {
         // Start Mocking
         using (RecordExpectations recorder = new RecordExpectations())
         {
            Testee testee = new Testee();
            testee.Foo();
            recorder.Return(22);
         }
         // END OF MOCK SETUP

         // Lets call it
         Assert.AreEqual(22, new Testee().Foo());
      }
   }
}


Testee
namespace TMDataSetProblem
{
   public class Testee
   {
      public int Foo()
      {
         new System.Data.DataSet();
         return 1;
      }
   }
}


When this test runs, I get the following failure output:
------ Test started: Assembly: TMDataSetProblem.dll ------

TestCase 'TMDataSetProblem.Tester.DataSetProblem'
failed: 
TearDown : System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
  ----> TypeMock.VerifyException : 
TypeMock Verification: Method <CrtImplementationDetails>.ModuleUninitializer.AddHandler() has 1 more expected calls

   
   --TearDown
   at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at NUnit.Core.TestMethod.doTearDown(TestCaseResult testResult)
   --TargetInvocationException
   at TypeMock.MockManager.Verify()
   C:devTMDataSetProblemTMDataSetProblemNewDataSetCausesExtraExpectation.cs(14,0): at TMDataSetProblem.Tester.Finish()


0 passed, 1 failed, 0 skipped, took 1.61 seconds.




If I remove the new System.Data.DataSet(); statement from the Foo method, the test runs fine. What is going on?
asked by hebbja (1.2k points)

3 Answers

0 votes
Strange, I cant seem to reproduce the problem.
What is happening is that the CLR is calling an extra internal method the first time Testee is called (you will see this if you run the TypeMock Tracer).
But because we are in the recorder this method doesn't get called.

We need to fix this. In the meantime here is a workaround:
[Test]
public void DataSetProblem()
{
  // Workaround just call any method in the module to initialize.
  new Testee();
  // Start Mocking
  using (RecordExpectations recorder = new RecordExpectations())
  {
     Testee testee = new Testee();
     testee.Foo();
     recorder.Return(22);
   } 
   // END OF MOCK SETUP
   ...
} 
answered by scott (32k points)
0 votes
Thanks. For me, your suggested workaround did not work. It did, however, prompt me to discover that, for this case at least, my minimal requirement is to create an instance of the System.Data.DataSet class before recording to make this error go away:

      [Test]
      public void DataSetProblem()
      {
         [b]// Required to make the <CrtImplementationDetails>.ModuleUninitializer.AddHandler error go away
         new System.Data.DataSet();[/b]

         // Start Mocking
         using (RecordExpectations recorder = new RecordExpectations())
         {
            ...


Thanks for your help.
answered by hebbja (1.2k points)
0 votes
Great,
I will send you a fix offline, once we manage to reproduce the problem.
answered by scott (32k points)
...