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
Hi

I get the following exception when running a unit test using Natural TypeMocks:

TestCase 'Sanlam.SanQuote.Business.Domain.UnitTest.FinaliseApplicationTransitionFixture.TestValidFinaliseApplicationTransition'
failed: System.Reflection.AmbiguousMatchException : Ambiguous match found.
at System.DefaultBinder.BindToMethod(BindingFlags bindingAttr, MethodBase[] canidates, Object[]& args, ParameterModifier[] modifiers, CultureInfo cultureInfo, String[] names, Object& state)
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at TypeMock.MockManager.MockObject(Type type, Constructor mockConstructors, Object[] args)
at TypeMock.MockManager.a(Type A_0, Constructor A_1, Object[] A_2)
at TypeMock.MockManager.b(Type A_0)
at TypeMock.RecorderManager.a(MethodInfo A_0, String A_1, Object A_2, Object[] A_3, MethodBase A_4, Boolean A_5, Type A_6)
at TypeMock.RecorderManager.a(String A_0, String A_1, Object A_2, Object[] A_3, MethodBase A_4, Object A_5)
at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Object[] A_4)
at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Object p1, Object p2)
C:\Projects\Phoenix 3.0\Code\Sanlam.SanQuote.Business.Domain\Agreement\Services\DocumentGeneratorService.cs(29,0): at Sanlam.SanQuote.Business.Domain.Agreement.DocumentGeneratorService.GenerateDocumentInAgreement(Agreement agreement, DocumentType documentType)
C:\Projects\Phoenix 3.0\Code\Sanlam.SanQuote.Business.Domain.UnitTest\Agreement\StateTransitions\FinaliseApplicationTransitionFixture.cs(73,0): at Sanlam.SanQuote.Business.Domain.UnitTest.FinaliseApplicationTransitionFixture.TestValidFinaliseApplicationTransition()


Here is the actual unit test:
   [Test]
      public void TestValidFinaliseApplicationTransition()
      {
         MockManager.Init();

         using (Session session = DataLayerRegistry.Instance.DomainModel.CreateSession())
         {
            Domain.Agreement.Agreement agreement = CreateInProgressApplication(session);
            AgreementStateTransition stateTransition =
               AgreementStateTransitionFactory.Create(agreement, AgreementTransition.FinaliseApplication);

            ValidationContext context = new ValidationContext(); 
            context.Action = (long)Actions.Finalise;

            IList<DocumentType> documentTypes = new DocumentType[] { DocumentType.Application , DocumentType.Declaration,
                                                                     DocumentType.DebitOrder, DocumentType.DepositSlip };

            // Mock external calls to other service classes that happens on the transition and verify
            // that they were executed with the right arguments
            using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
               recorder.ExpectAndReturn(agreement.GetAllowedDocumentTypes(), documentTypes);

               DocumentGeneratorService.GenerateDocumentAndPdfAttachmentInAgreement(agreement, DocumentType.Application);
               DocumentGeneratorService.GenerateDocumentInAgreement(agreement, DocumentType.Declaration);
               DocumentGeneratorService.GenerateDocumentInAgreement(agreement, DocumentType.DebitOrder);
               DocumentGeneratorService.GenerateDocumentInAgreement(agreement, DocumentType.DepositSlip);

               UpdateMasterPartyService.UpdateMasterParty(context, agreement);

               recorder.CheckArguments();
            }

            RuleResult result = stateTransition.Execute(context);

            // Ensure no validation errors
            Assert.IsTrue(result.HasNoErrors, "No error should occur on a valid finalise transition");
         }

         MockManager.Verify();
      }


The exception occurs as soon as the 2nd call is made to the DocumentGeneratorService. Here is the code for the DocumentGeneratorService:

  public static class DocumentGeneratorService
   {
      public static void GenerateDocumentAndPdfAttachmentInAgreement(Agreement agreement, DocumentType documentType)
      {
         ValidationHelper.ValidateParameterIsCompleted(agreement, "agreement");
         ValidationHelper.ValidateParameterIsCompleted(documentType, "documentType");

         Document document = GenerateDocumentInAgreement(agreement, documentType);

         if (document.Content != null)
         {
            Attachment attachment = GenerateAttachmentInAgreement(agreement, documentType.PdfAttachmentType);
            AttachmentPage page = attachment.CreateAttachmentPage();
            page.Content = PdfConverter.ConvertToPdf(document.Content);
            attachment.AddAttachmentPage(page);
         }
      }
      
      public static Document GenerateDocumentInAgreement(Agreement agreement, DocumentType documentType)
      {
         Document document = agreement.FindDocument(documentType);
         if (document != null)
         {
            agreement.RemoveDocument(document);
         }
         document = agreement.CreateDocument(documentType);
         agreement.AddDocument(document);
         return document;
      }

      public static Attachment GenerateAttachmentInAgreement(Agreement agreement, AttachmentType attachmentType)
      {
         Attachment attachment = agreement.FindAttachment(attachmentType);
         if (atta
asked by cjlotz (3k points)

9 Answers

0 votes
Hi,
You have found a bug, we will fix it and send you a patch offline.
answered by scott (32k points)
0 votes
Hi
I sent you the patch offline.
Check your mailbox ...
answered by ohad (35.5k points)
0 votes
Ohad

The original AmbiguousMatchException no longer appears, but the test still fails. When I exercise the code via our UI, the code functions correctly, however when I run the unit test it fails with the following error message:

TestCase 'Sanlam.SanQuote.Business.Domain.UnitTest.FinaliseApplicationTransitionFixture.TestValidFinaliseApplicationTransition'
failed: TypeMock.VerifyException :
TypeMock Verification: Method Sanlam.SanQuote.Business.Domain.Agreement.DocumentGeneratorService.GenerateDocumentInAgreement() has 2 more expected calls

at TypeMock.MockManager.Verify()
C:\Projects\Phoenix 3.0\Code\Sanlam.SanQuote.Business.Domain.UnitTest\Agreement\StateTransitions\FinaliseApplicationTransitionFixture.cs(94,0): at Sanlam.SanQuote.Business.Domain.UnitTest.FinaliseApplicationTransitionFixture.TestValidFinaliseApplicationTransition()


Here is the code that is being tested:
using System.Collections.Generic;
using Sanlam.SanQuote.Validation;

namespace Sanlam.SanQuote.Business.Domain.Agreement
{
   /// <summary>
   /// State transition class containing the functionality for moving from the <see cref="AgreementStates.InProgressApplication"/> 
   /// state to the <see cref="AgreementStates.FinalisedApplication"/> state.
   /// </summary>
   internal sealed class FinaliseApplicationTransition : AgreementStateTransition
   {
      #region Constructors + Destructors

      public FinaliseApplicationTransition(Agreement context)
         : base(context)
      {
      }

      #endregion

      #region Private Members

      /// <summary>
      /// Generates the documents for the finalisation of the application.
      /// </summary>
      /// <param name="context">The context.</param>
      private void GenerateApplicationDocuments(ValidationContext context)
      {
         IList<DocumentType> documentTypes = Agreement.GetAllowedDocumentTypes();
         
         DocumentGeneratorService.GenerateDocumentAndPdfAttachmentInAgreement(Agreement, DocumentType.Application);
         DocumentGeneratorService.GenerateDocumentInAgreement(Agreement, DocumentType.Declaration);

         if (documentTypes.Contains(DocumentType.DebitOrder))
         {
            DocumentGeneratorService.GenerateDocumentInAgreement(Agreement, DocumentType.DebitOrder);
         }
         if (documentTypes.Contains(DocumentType.DepositSlip))
         {
            DocumentGeneratorService.GenerateDocumentInAgreement(Agreement, DocumentType.DepositSlip);
         }
      }

      #endregion
      
      #region Protected Members

      /// <summary>
      /// Gets the end state in which a successful transition will end off in.
      /// </summary>
      protected override AgreementStates EndState
      {
         get
         {
            return AgreementStates.FinalisedApplication;
         }
      }

      /// <summary>
      /// Template method to execute state transition specific functionality within the context
      /// </summary>
      /// <param name="context">Context in which to perform the transition</param>
      protected override void OnExecute(ValidationContext context)
      {
         // Generate the application documents
         GenerateApplicationDocuments(context);

         // Update the master party data
         UpdateMasterPartyService.UpdateMasterParty(context, Agreement);
      }

      #endregion

   }
}


When I step through the code with the debugger, it turns out that it doesn't pick up the DebitOrder and DepositSlip document types that I returned as the arguments for the mocked Agreement.GetAllowedDocumentTypes() call. The If conditions in the GenerateApplicationDocuments sub therefore fails which generates the 2 missing calls exception. As mentioned, this works correctly when exercising the code through the UI. I also include the code of the mocked Agreement.GetAllowedDocumentTypes call.

      /// <summary>
      /// Gets the document types that is allowed for the current agreement state.
      /// </summary>
      /// <returns>List of document types applicable for the state</returns>
      public IList<DocumentType> GetAllowedDocumentTypes()
      {
         List<DocumentType> documentTypes = new List<DocumentType>();
         switch (State)
         {
            case AgreementStates.InProgressQuote:
            case AgreementStates.FinalisedQuote:
               documentTypes.Add(DocumentType.NoteToIntermediary);
               documentTypes.Add(DocumentType.Quotation);
               break;

            case AgreementStates.InProgressApplication:
            case AgreementStates.FinalisedApplication:
               documentTypes.Add(DocumentType.Application);
               documentTypes.Add(DocumentType.Declaration);

               if (HasRecurringContractualPayment ?? false)
               {
                  RecurringContractualPayment payment = FindContractualPayment<RecurringContractualPayment>();
                  if (payment.PaymentDetails is DebitOrderPaymentDetails)
                  {
                     documentTypes.Add(DocumentType.DebitOrder);
                  }
                  if (payment.InitialPayment != null)
                  {
                     if (payment.InitialPayment.Mode == ModeOfPayment.ABSATeller || payment.InitialPayment.Mode == ModeOfPayment.FNBBankTeller)
  
answered by cjlotz (3k points)
0 votes
Hi Carl
Can you please run the failed test with the Tracer log?
To run the Tracer:
Start -> Programs -> TypeMock.NET -> Tracer

After the test is finished save the log file:
File -> Save...

Then please send me the saved file.
answered by ohad (35.5k points)
0 votes
Ohad

Any news? I send the log through to your mailbox yesterday.
answered by cjlotz (3k points)
0 votes
Hi
Sorry I did not get any mail from you.
I will send you a different address.
answered by ohad (35.5k points)
0 votes
Hi Carl
The problem is that you are mocking DocumentType.Application , DocumentType.Declaration etc ...
As a result the if statement in GenerateApplicationDocuments method is actually dealing with a mocked values.
I think that what you are trying to do is this:

            using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
                recorder.ExpectAndReturn(agreement.GetAllowedDocumentTypes(), documentTypes);

                DocumentGeneratorService.GenerateDocumentAndPdfAttachmentInAgreement(agreement, null);
                DocumentGeneratorService.GenerateDocumentInAgreement(agreement, null);
                DocumentGeneratorService.GenerateDocumentInAgreement(agreement, null);
                DocumentGeneratorService.GenerateDocumentInAgreement(agreement, null);

                UpdateMasterPartyService.UpdateMasterParty(context, agreement);
                recorder.CheckArguments();
            }


Note that recorder.CheckArguments();
will check only the last call.
answered by ohad (35.5k points)
0 votes
Thanks Ohad

Will this fix be included in the next release? When will the next release be made available?

Thanks
answered by cjlotz (3k points)
0 votes
Hi Carl
Yes the fix will be included in our next release.
The release will will be out on the wild 8) next week.
answered by ohad (35.5k points)
...