FlexLabs.Upsert icon indicating copy to clipboard operation
FlexLabs.Upsert copied to clipboard

Unit test against Upsert

Open djmnz opened this issue 3 years ago • 4 comments

Thanks for the extension! Saved me heaps!

If I have a class consuming this extension, what is the recommended method to unit test the On method, and the WhenMatched?

For example: validate the correct On values, and the correct updated values when matched.

Any suggestions?

djmnz avatar Apr 11 '21 04:04 djmnz

Heya,

Hmm. There's no easy way to stub it, since the library generates SQL statements that it sends to the server, rather than using EF's internal state management.

I guess the best way to test your service is to use an InMemory database, and then check the data after the updates? The upsert library supports the InMemory provider, and I use it (alongside the other providers) in the library's unit tests

Would that work in your case, or do you have a different scenario where a different approach is needed?

artiomchi avatar Jul 11 '21 13:07 artiomchi

Can we at least have interfaces instead of classes with internal constructors (for UpsertCommandBuilder)?

ToniaDemchuk avatar Dec 29 '21 14:12 ToniaDemchuk

Note that all of MS's guidance for unit testing and EF Core strongly discourage using the in-memory provider for unit testing:

https://docs.microsoft.com/en-us/ef/core/testing/choosing-a-testing-strategy

As an alternative to SQLite, EF Core also comes with an in-memory provider. Although this provider was originally designed to support internal testing of EF Core itself, some developers use it as a database fake when testing EF Core applications. Doing so is highly discouraged

https://docs.microsoft.com/en-us/ef/core/testing/testing-without-the-database#inmemory-provider

As discussed in the testing overview page, using the in-memory provider for testing is strongly discouraged

nwoolls avatar Aug 10 '22 16:08 nwoolls

FWIW I was able to handle this by extending my repository pattern a bit with the following implementation:


/// <inheritdoc />
public async Task<int> Upsert(Models.Widget widget)
{
    return await Widgets
        .Upsert(widget)
        .NoUpdate()
        .RunAsync();
}

/// <inheritdoc />
public async Task<int> Upsert(Models.Widget widget, Expression<Func<Models.Widget, Models.Widget>> updater)
{
    return await Widgets
        .Upsert(widget)
        .WhenMatched(updater)
        .RunAsync();
}

/// <inheritdoc />
public async Task<int> Upsert(Models.Widget widget, Expression<Func<Models.Widget, Models.Widget, Models.Widget>> updater)
{
    return await Widgets
        .Upsert(widget)
        .WhenMatched(updater)
        .RunAsync();
}

nwoolls avatar Aug 10 '22 17:08 nwoolls