Unit Testing Save of editable stereotypes with Moq

Unit Testing Save of editable stereotypes with Moq

Old forum URL: forums.lhotka.net/forums/t/12843.aspx


coding posted on Tuesday, March 10, 2015

we are using Moq with csla for unit testing. Moq is working fine with mocking fetch calls but not working with mocking save call of editable business base.

 While saving, as we mock the child lists "create" calls, editable BO becomes invalid and hence not savable. As it is pure mocking and child create call is not run, so business rules of list and list items dont fire, so not sure why the mocked list shows invalid.

Please respond back with article/code sample on how to mock save of editable BO and editable BO lists with Moq.

 

Thanks !!

ajj3085 replied on Tuesday, March 10, 2015

I'm assuming you have interfaces for the child objects and that's what you mean by mocking the child lists.  If you do nothing, mocks will return the default(T) value where T is the type of the property.  For IsValid, that would be false.  So you'll have to make your mocks return true for IsValid, as Csla just iterates the children and queries that flag to determine if they are valid or not.

JonnyBee replied on Wednesday, March 11, 2015

Hi,

And remember IsDirty must also be true or else the Save method will just return the "unmodified" object. 

protected async virtual System.Threading.Tasks.Task<T> SaveAsync(bool forceUpdate, object userState, bool isSync)
{
  if (forceUpdate && IsNew)
  {
    // mark the object as old - which makes it
    // not dirty
    MarkOld();
    // now mark the object as dirty so it can save
    MarkDirty(true);
  }
  T result;
  if (this.IsChild)
    throw new InvalidOperationException(Resources.NoSaveChildException);
  if (EditLevel > 0)
    throw new InvalidOperationException(Resources.NoSaveEditingException);
  if (!IsValid && !IsDeleted)
    throw new Rules.ValidationException(Resources.NoSaveInvalidException);
  if (IsBusy)
    throw new InvalidOperationException(Resources.BusyObjectsMayNotBeSaved);
  if (IsDirty)
  {
    if (isSync)
    {
      result = DataPortal.Update<T>((T)this);
    }
    else
    {
      MarkBusy();
      try
      {
        result = await DataPortal.UpdateAsync<T>((T)this);
      }
      finally
      {
        MarkIdle();
      }
    }
  }
  else
  {
    result = (T)this;
  }
  OnSaved(result, null, userState);
  return result;
}

coding replied on Wednesday, March 11, 2015

yes i have interfaces for child objects, as suggested i did setupget for is valid property but recieving mock serialization error now, pls suggest

 

 

 

 

 

var mockchildlist = new Mock<Ichildlist>();

mockchildlist.SetupGet(_ => _.IsValid).Returns(

 

true);

 

 

 

 

var

 

 

mockchildlistFactory = new Mock<IObjectFactory<Ichildlist>>(MockBehavior.Strict);

mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(mockchildlist.Object);

 

 

 

var mockchildFactory = new Mock<IObjectFactory<IChild>>(MockBehavior.Strict);

 

 

var builder = new ContainerBuilder();

builder.Register<

 

IObjectFactory<IMychildlist>>(_ => mockchildlistFactory.Object);

builder.Register<

IObjectFactory<IChild>>(_ => imageTagFactory.Object);

 

IObjectFactory<IChild>>(_ => imageTagFactory.Object);

IObjectFactory<IChild>>(_ => imageTagFactory.Object);

 

 

 

 

 

 

 

 

 

parentBO=

 

await DataPortal.CreateAsync<T>();

parentBO.//property setters

parentBO=

 

await parentBO.SaveAsync();

// we are using abstractions in csla concept http://magenic.com/BlogArchive/AbstractionsinCSLA

Error :System.Runtime.Serialization.SerializationException: Type 'Moq.Proxy.ProxyMethodHook' in Assembly 'Moq, Version=4.2.1502.911, Culture=neutral, PublicKeyToken=69f491c39445e920' is not marked as serializable.

coding replied on Wednesday, March 11, 2015

yes i have interfaces for child objects, as suggested i did setupget for is valid property but recieving mock serialization error now, pls suggest var mockchildlist = new Mock(); mockchildlist.SetupGet(_ => _.IsValid).Returns(true); var mockchildlistFactory = new Mock>(MockBehavior.Strict); mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(mockchildlist.Object); var mockchildFactory = new Mock>(MockBehavior.Strict); var builder = new ContainerBuilder(); builder.Register>(_ => mockchildlistFactory.Object); builder.Register>(_ => imageTagFactory.Object); parentBO= await DataPortal.CreateAsync(); parentBO.//property setters parentBO= await parentBO.SaveAsync(); // we are using abstractions in csla concept http://magenic.com/BlogArchive/AbstractionsinCSLA Error :System.Runtime.Serialization.SerializationException: Type 'Moq.Proxy.ProxyMethodHook' in Assembly 'Moq, Version=4.2.1502.911, Culture=neutral, PublicKeyToken=69f491c39445e920' is not marked as serializable.

ajj3085 replied on Wednesday, March 11, 2015

Do you have a remote data portal configured for your unit tests?  Have you tried Save and not SaveAsync?  Something is trying to serialize a type from Mow which is as the error says nit serializable.

coding replied on Sunday, March 15, 2015

Hi

Another point, I wanted to add, when I tries Dataportal.UpdateChild(childBO) with mock child list in the above code, this serialization error did not occur. Does that also give a clue regarding the error ?

JonnyBee replied on Thursday, March 12, 2015

Save actually calls SaveAsync with parameter for sync (boo).

ajj3085 replied on Thursday, March 12, 2015

JonnyBee
Save actually calls SaveAsync with parameter for sync (bool).

Yes, but IIRC if sync is false Csla will actually create a Task to run the operation as async, but if its false it won't.  My thinking is that actually doing something as async is triggering serialization and deserializing isn't finding the Moq assembly. 

coding replied on Thursday, March 12, 2015

JonnyBee

Save actually calls SaveAsync with parameter for sync (boo).

 

Hi

I tried using returning an actual child list through mock, it worked ! not sure if this is the correct approach , does it give any clue to serialization problem ?

// old mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(mockchildlist.Object);

//new mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(new ChildList ());

Do you have any code sample /article which shows how to do unit testing of save of editable root and editable root list child CRUD with MOQ ??

Suppose we save root editable object with child lists , basically what all steps we need to mock ? As I know calling save/saveasync will land on Dataportal_update, so do we need to mock child list for mocking as save operation will tend to save the entire object graph ?

 

coding replied on Friday, March 13, 2015

coding

[quote user="JonnyBee"]

Save actually calls SaveAsync with parameter for sync (boo).

Hi

I tried using returning an actual child list through mock, it worked ! not sure if this is the correct approach , does it give any clue to serialization problem ?

// old mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(mockchildlist.Object);

//new mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(new ChildList ());

Do you have any code sample /article which shows how to do unit testing of save of editable root and editable root list child CRUD with MOQ ??

Suppose we save root editable object with child lists , basically what all steps we need to mock ? As I know calling save/saveasync will land on Dataportal_update, so do we need to mock child list for mocking as save operation will tend to save the entire object graph ?

Another point, I wanted to add, when I tries Dataportal.UpdateChild(childBO) with mock child list in the above code, this serialization error did not occur. Does that also give a clue regarding the error ?

 

coding replied on Sunday, March 15, 2015

Another point, I wanted to add, when I tries Dataportal.UpdateChild(childBO) with mock child list in the above code, this serialization error did not occur. Does that also give a clue regarding the error ?

coding replied on Thursday, March 12, 2015

Andy

Do you have a remote data portal configured for your unit tests?  Have you tried Save and not SaveAsync?  Something is trying to serialize a type from Mow which is as the error says nit serializable.

Hi

I tried using returning an actual child list through mock, it worked ! not sure if this is the correct approach , does it give any clue to serialization problem ?

// old mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(mockchildlist.Object);

//new mockchildlistFactory.Setup(_ => _.CreateChild()).Returns(new ChildList ());

Do you have any code sample /article which shows how to do unit testing of save of editable root and editable root list child CRUD with MOQ ??

Suppose we save root editable object with child lists , basically what all steps we need to mock ? As I know calling save/saveasync will land on Dataportal_update, so do we need to mock child list for mocking as save operation will tend to save the entire object graph ?

 

 

coding replied on Sunday, March 15, 2015

Hi Andy,

Another point, I wanted to add, when I tries Dataportal.UpdateChild(childBO) with mock child list in the above code, this serialization error did not occur. Does that also give a clue regarding the error ?

ajj3085 replied on Sunday, March 22, 2015

Maybe.  It could be that async is causing things to cross appdomain boundaries.  So have you tried changing your test to just call Save instead of SaveAsync.

 

Also, pleas refrain from double posting.  Messages are moderated in this forum, so they won't appear until they are approved.  please be patient.

JasonBock replied on Saturday, April 04, 2015

Try putting this in the config file of your test project:

<add key="CslaAutoCloneOnUpdate" value="false" />

This effectively turns off serialization for CSLA, which should eliminate your serialization issue. Don't do this with production systems, just for test.

Copyright (c) Marimer LLC