locked
Unit Test a Custom Provider RRS feed

  • Question

  • How would you go about writing unit tests for a custom provider? Any suggestions welcome. 

    Thanks
    George
    Wednesday, March 10, 2010 12:39 AM

Answers

  • Hi George,

    Do you mean functional tests when you say unit tests?

    Unit tests are usually written to test individual components within custom provider, so it would be hard to give suggestions unless the design is shared.

    If you meant functonal tests, you might have some basic functional test scnearios such as

    - insert some data on source, sync to destination, make additional local changes such as insert, update, delete, perfor more syncs, etc...
    - do you handle conflicts? if so, create conflicting situations (i.e. update - update, update - delete, etc....)
    - do you handle local constraints? if so, try to apply a sync change that cannot be persisted because of your data constraint (i.e. cannot have two contacts with same phone number, etc...)

    Hope this helps,

    Patrick
    Thursday, March 11, 2010 7:57 PM
  • Hi George,

    As Sid mentioned, a lot of things in SyncFx has private constructors (even setters and getters). I agree it's not your typical everyday unit test scenario. But I wouldn't want to spend much of my time using reflection to mock the SyncFx objects. I would want to focus my time on the code under test.

    Tuesday, March 16, 2010 1:28 AM
  • Hi George, as discussed by Patrick and JuneT, integration testing is the way to go. Of course, stepping through your code while running a test is recommended, to test out all blocks of your code to make sure. Where you can add unit tests for complex methods, you should, but if there are blockers, such as not being able to mock objects, you may have to balance effort versus returns.

    When you call a recoverable error, that item is skipped, and the replica knowledge is appropriately marked, so that next time sync is attempted again, the source replica knows this item hasn't been synced yet and the destination knowledge hasn't learned about the latest version. So this item will be synced again during the next sync.

    A quick way to test this is to sync 1 item, set recoverable error, then verify that sync session statistics returns 0 applied, 1 failed. Sync again, this time with no recoverable error, and sync session statistics should return 1 applied, 0 failed. A third sync will be an empty sync.
    Tuesday, March 16, 2010 1:35 AM

All replies

  • Hi George,

    Do you mean functional tests when you say unit tests?

    Unit tests are usually written to test individual components within custom provider, so it would be hard to give suggestions unless the design is shared.

    If you meant functonal tests, you might have some basic functional test scnearios such as

    - insert some data on source, sync to destination, make additional local changes such as insert, update, delete, perfor more syncs, etc...
    - do you handle conflicts? if so, create conflicting situations (i.e. update - update, update - delete, etc....)
    - do you handle local constraints? if so, try to apply a sync change that cannot be persisted because of your data constraint (i.e. cannot have two contacts with same phone number, etc...)

    Hope this helps,

    Patrick
    Thursday, March 11, 2010 7:57 PM
  • hi George,

    if it's a database provider, you can find some sample tests on the SQL Express client provider sample: http://code.msdn.microsoft.com/sync/Release/ProjectReleases.aspx?ReleaseId=1200
    Thursday, March 11, 2010 11:09 PM
  • Hi

    Thanks for your reply. I did actually mean unit testing, but I'm open to suggestions. What I had in mind was, performing tests against the public method of the provider, UpdateItem for instance. I was thinking I could use dependency injection and mock the objects that actually interact with the data. The tests could then check that the state of the object is updated is correctly. Problems arise when it comes to classes like RecoverableErrorReportingContext, as this class has a private constructor; so I can't test that, when an instance of RecoverableErrorReportingContext is passed X happens. Without wrapping the entire framework I can't mock it either as the class does not implement any interface.

    So integration testing is the way to go with this? I can still mock the actual interaction with the data store, so the test wouldn't have to rely on data connections, so I guess that would be okay. 

    A slight aside, what should happen when RecoverableErrorReportingContext.RecordRecoverableErrorForChange(errorData As RecoverableErrorData) is called?

    Thanks
    George
    Thursday, March 11, 2010 11:31 PM
  • JuneT, thanks for the link, your input is appreciated. It is interesting to see that these test are system tests -- they are been performed against the actual store. I thought there would be some examples of testing at smaller, more defined -- unit -- level. I'm new to unit testing though, is it just that there is not enough value in testing such a small unit? 

    George
    Thursday, March 11, 2010 11:47 PM
  • Hi George,

    I believe it's always valuable having tests. In the case of SyncFx, I just find it tedious creating the mocks. Here's another example for you: http://rickgaribay.net/archive/2009/08/17/unit-testing-microsoft-sync-framework-amp-wcf.aspx

    Monday, March 15, 2010 1:47 PM
  • Hi

    In the example the developer is mocking types they "do not own" I understand this to be a bad practice, and that you should instead wrap/adapt the third party classes. However I think this would incur a lot of work as I'd have to translate between my own classes and the frameworks. In your opinion, is the Publicize.exe method the best option for this scenario?

    Thanks
    George
    Monday, March 15, 2010 4:09 PM
  • Hi George - for the Sync Framework types with private constructors, you will have to use reflection to "mock" them. Is this what JuneT is doing? Or using a similarly defined test class?
    Monday, March 15, 2010 5:34 PM
  • Hi George,

    As Sid mentioned, a lot of things in SyncFx has private constructors (even setters and getters). I agree it's not your typical everyday unit test scenario. But I wouldn't want to spend much of my time using reflection to mock the SyncFx objects. I would want to focus my time on the code under test.

    Tuesday, March 16, 2010 1:28 AM
  • Hi George, as discussed by Patrick and JuneT, integration testing is the way to go. Of course, stepping through your code while running a test is recommended, to test out all blocks of your code to make sure. Where you can add unit tests for complex methods, you should, but if there are blockers, such as not being able to mock objects, you may have to balance effort versus returns.

    When you call a recoverable error, that item is skipped, and the replica knowledge is appropriately marked, so that next time sync is attempted again, the source replica knows this item hasn't been synced yet and the destination knowledge hasn't learned about the latest version. So this item will be synced again during the next sync.

    A quick way to test this is to sync 1 item, set recoverable error, then verify that sync session statistics returns 0 applied, 1 failed. Sync again, this time with no recoverable error, and sync session statistics should return 1 applied, 0 failed. A third sync will be an empty sync.
    Tuesday, March 16, 2010 1:35 AM
  • Thanks, all, for your advice.

    Sid, thanks for the information regarding recoverable error. 


    Tuesday, March 16, 2010 6:46 PM