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 !!
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.
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; }
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 builder = new ContainerBuilder();
builder.Register< IObjectFactory<IMychildlist>>(_ => mockchildlistFactory.Object);
builder.Register<
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.
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
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 ?
Save actually calls SaveAsync with parameter for sync (boo).
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.
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 ?
[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 ?
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 ?
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 ?
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 ?
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.
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