So I’m still suffering from working with Crystal Reports. Here’s some funniness I’m having trouble understanding.. maybe YOU can help!

I’m trying to calculate a page count for a section in a crystal report. Here’s what my test looks like:

[Test] 
  public void Should_Be_Able_To_Calculate_Page_Count( ) 
  {
    MockRepository mockery = new MockRepository( );
    ReportDocument stubReport = mockery.Stub< ReportDocument >( );
    FormatEngine stubEngine = mockery.Stub< FormatEngine >( );

    using( mockery.Record( ) ) 
    {
      Expect.Call( stubReport.FormatEngine ).Return( stubEngine );
      Expect.Call( stubEngine.GetLastPageNumber( null ) ).IgnoreArguments( ).Return( 1 );
    } 

    using( mockery.Playback( ) ) 
    {
      int count = new ExecutiveSummarySection( stubReport ).CalculatePageCount( );
      Assert.AreEqual( 1, count );
    }
  }

I’m trying to retrieve the last page number for a section in a crystal report so that i can generate a table of contents. It seems that this trivial task isn’t as easy as I believe it should be, so this is my work around. The code to pass this test looks like this:

internal class ExecutiveSummarySection 
  {
    public ExecutiveSummarySection( ReportDocument report ) 
    {
      _report = report;
    }

    public int CalculatePageCount( ) 
    {
      return _report.FormatEngine.GetLastPageNumber( new ReportPageRequestContext( ) );
    }

    private readonly ReportDocument _report;
  }

But when I run the test I get this error…

Tests run: 398, Failures: 1, Skipped: 0, Ignored: 0
    Failures:
    1) ExecutiveSummaryTest.Should_Be_Able_To_Calculate_Page_Count :
    Can't find a constructor with matching arguments
     at Rhino.Mocks.MockRepository.MockClass(CreateMockState mockStateFactory, Type type, Type[] extras, Object[] argumentsForConstructor)
     at Rhino.Mocks.MockRepository.CreateMockObject(Type type, CreateMockState factory, Type[] extras, Object[] argumentsForConstructor)
     at Rhino.Mocks.MockRepository.Stub(Type type, Object[] argumentsForConstructor)
     at Rhino.Mocks.MockRepository.Stub[T](Object[] argumentsForConstructor)
     at ExecutiveSummaryTest.Should_Be_Able_To_Calculate_Page_Count() in c:\development\MediaLogic\...\ExecutiveSummaryTest.cs:line 13

I don’t get it… so i popped open reflector to see what I might be able to find. It turns out that the “FormatEngine” type is located in an assembly called “CrystalDecisions. CrystalReports.Engine” which is installed in the GAC. (I haven’t quite found out how to pull this out of the GAC so that we can xcopy deploy this assembly with the rest, and i don’t believe you can. Correct me if i’m wrong, please!)

Also, the constructor on “FormatEngine” is defined as ‘internal’. I noticed that the “FormatEngine” type is implementing the interface “IReportSource”. So I tried stubbing that out instead in place of the “FormatEngine” property on the “ReportDocument”. On got this message:

Tests run: 398, Failures: 1, Skipped: 0, Ignored: 0
    Failures:
    1) ExecutiveSummaryTest.Should_Be_Able_To_Calculate_Page_Count :
    Type 'IReportSourceProxyb9462264e9bb45c1a40d67229a43aa9c' doesn't match the return type 'CrystalDecisions.CrystalReports.Engine.FormatEngine' for method 'ReportDocument.get_FormatEngine();'
     at Rhino.Mocks.Expectations.AbstractExpectation.AssertTypesMatches(Object value)
     at Rhino.Mocks.Expectations.AbstractExpectation.set_ReturnValue(Object value)
     at Rhino.Mocks.Impl.MethodOptions.Return(Object objToReturn)
     at ExecutiveSummaryTest.Should_Be_Able_To_Calculate_Page_Count() in c:\development\MediaLogic\...\ExecutiveSummaryTest.cs:line 16

That makes sense… So how do i get around this?

comments powered by Disqus