Mocking AutoGenerated DB Indentity Field in Entity Framework 6, DBFirst Project

1,029 views
Skip to first unread message

GianPiero Bresolin

unread,
Oct 27, 2015, 4:01:14 PM10/27/15
to NSubstitute
Hello, I have successfully mocked out a DBContext so that I can test my Entity Framework implementations, using the following lines:

//Initialize our source of ProductRequest MockedData
           
var productRequestMockSet = new ProductRequestMocks();
           
var productRequestData = productRequestMockSet.Initialize();

           
// Create a DbSet substitute.
           
var productRequestDbSet = Substitute.For<DbSet<ProductRequest>, IQueryable<ProductRequest>, IDbAsyncEnumerable<ProductRequest>>()
                               
.SetupData(productRequestData);

           
//Initialize our Mocked DbContext
            _context
= Substitute.For<SOURCINGEntities>();
            _context
.ProductRequests.Returns(productRequestDbSet);

However when I add records to the ProductRequests entity, my PK field ID is not been auto incremented as it would if I was using the actual database (The ID field is set to auto increment within SQL).  Is there anyway I can get this behavior to occur using NSubstitute, as some of my newer tests require this?

I have tried adding the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] attribute to my Db Context, but this has no effect. And ideally I would like to avoid changing anything in the EF autogenerated files as they are overwritten every time the DB is refreshed.

Any help would be appreciated.

Kind regards
GianPiero

David Tchepak

unread,
Oct 27, 2015, 7:32:10 PM10/27/15
to nsubs...@googlegroups.com
Hi GianPiero,
I'm not familiar with EF sorry. Maybe try posting on stackoverflow.com?

At a rough guess, if you can hook into the `Add` method, you could try something like:

    var nextId = 1;
    sub.WhenForAnyArgs(x => x.Add(null))
          .Do(x => x.Args<Record>().Id = nextId++)

I'm not sure if that will work in this instance but it might give you some ideas. There is a little more about When..Do here: 

Regards,
David

--
You received this message because you are subscribed to the Google Groups "NSubstitute" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nsubstitute...@googlegroups.com.
To post to this group, send email to nsubs...@googlegroups.com.
Visit this group at http://groups.google.com/group/nsubstitute.
For more options, visit https://groups.google.com/d/optout.

GianPiero Bresolin

unread,
Nov 18, 2015, 12:07:39 PM11/18/15
to NSubstitute
Hi David,

So sorry that I haven't responded, my apologies, I didn't seem to subscribed to the response, so I didn't know that you had replied.
Your response looks very promising, I will give it a try tomorrow and let you know what the results are.

Thanks for the help,
GianPiero

GianPiero Bresolin

unread,
Nov 19, 2015, 2:18:56 AM11/19/15
to NSubstitute
Dear David,

And anyone else who is listening. I went with the following in the end:

quoteDbSet.WhenForAnyArgs(x => x.Add(Arg.Any<Quote>()))
.Do(x => ((Quote)x[0]).QuoteID = quoteDbSet.Count() + 1);

So effectively what I am doing is when any Quote record is passed in to the Add method, increment that object's PK field (QuoteID) by the the count of the quoteDbSet +1.
This allows me to effectively mock out the auto incrementing PK.

Thanks for all your help David.

Kind regards
GianPiero

On Wednesday, 28 October 2015 01:32:10 UTC+2, David Tchepak wrote:

David Tchepak

unread,
Nov 19, 2015, 6:20:34 PM11/19/15
to nsubs...@googlegroups.com
Glad you got it sorted. Thanks for sharing the solution. :)

One minor tweak, you can avoid the cast using the CallInfo.Arg<T>() helper:
.Do(x => x.Arg<Quote>().QuoteID = quoteDbSet.Count() + 1);

You could also try Arg.Do [1], which would look something like this:
quoteDbSet.Add(Arg.Do<Quote>(x => x.QuoteID = quoteDbSet.Count()+1));
I find stubbing calls like that a bit confusing, but it is shorter and gives a bit of type safety to your argument match, so might be worth considering.

Regards,
David

GianPiero Bresolin

unread,
Nov 20, 2015, 1:00:31 AM11/20/15
to NSubstitute
Hey David,

Thanks for the update, definitely cleaner and much appreciated, thanks for sharing once again :)

Kind regards
GianPiero
Reply all
Reply to author
Forward
0 new messages