This is a migrated thread and some comments may be shown as answers.

FlushChanges() and Mocking

2 Answers 123 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
James Legan
Top achievements
Rank 1
James Legan asked on 13 Sep 2012, 05:06 PM
Quick question without going into too much detail. I am working on mocking out the database for unit testing of an IIS hosted WCF service. I was toying around with the idea of dependency injecting a context and possibly a transaction into a database handler and for unit testing only, have the transaction running with many, many FlushChanges() calls. Before I go through the effort of producing a proof of concept, what happens if I were to make a linq call on lets say a "Users" table (model.Users.Select(p => p).ToList()) for transactions have have been flushed but not committed? If I inserted a user, flushed it and then attempted a get, would I get back a user object w/its autoinc guid ID that otherwise would have been committed to SQL?

I realized this is not truly breaking the dependency on the DB but after a long running ticket with the justmock team and multiple samples going back and forth, I realized what I am trying to really achieve may not be possible. The "next best" would be running everything in memory without committing to the test DB which requires me to purge the data after every test run (not idea).

Thanks,

Jim

2 Answers, 1 is accepted

Sort by
0
James Legan
Top achievements
Rank 1
answered on 13 Sep 2012, 05:21 PM
Somewhat answered my own question regarding the ability to query objects that have been flushed. Now the question becomes transaction lifecycle. If individual methods have the context wrapped in a using statement:

using (var model = new VerifyModel())
                {
                    
                    var newUser = new User
                    {
                        Name = name,
                    };
 
                    model.Add(newUser);
                    model.FlushChanges();
                     
                    return newUser.Guid;
                }

Does the transaction go out of scope when control leaves the using statement or could this be persisted in a member variable without breaking good design principles?
0
Ralph Waldenmaier
Telerik team
answered on 17 Sep 2012, 08:38 AM
Hi James,

I am not sure if I fully understood what you want to achieve but let my try to help you.
If you want to flush data and query the data again in another method for your tests, I can think of a scenario where you encapsulate your test scenarios with a System.Transaction that can be Disposed if no data should be written to the database. 
See the following scrip as an example:

class Program
{
    private readonly static OpenAccessContext context = new EntitiesModel();
    static void Main(string[] args)
    {
        using (var txn = new System.Transactions.TransactionScope())
        {
            var newId = DoSomeInserts(0);
            DoSomeInserts(newId);
            txn.Dispose();
        }
        context.Dispose();
    }
     
    private static int DoSomeInserts(int newUserId)
    {
        var id = 0;
        var ctx = context as EntitiesModel;
        var cnt = ctx.Users.Where(x => x.UserId == newUserId).Count();
        Console.WriteLine("UserFound: " + cnt);
        var usr = new User() { Email = "some@someting.com", Name = "exampleuser" };
        ctx.Add(usr);
        ctx.FlushChanges();
        ctx.SaveChanges();
        id = usr.UserId;
        return id;
    }
}
As you can see I am setting up an OpenAccessContext that is later used in the method that should do the work. The result of this example is, that I am able to query the inserted user from the first call during the second call.
In the end I am disposing the TransactionScope and no data is written to my database.

If you would use individual context objects in your methods wit the using pattern, then you wouldn't be able to see the data that was inserted within another method, because you would operate on another connection to the database. 

I hope this answer is useful for you.
Feel free to ask if you have any other question.Regards,
Ralph
the Telerik team
Follow @OpenAccessORM Twitter channel to be the first one to get the latest updates on new releases, tips and tricks and sneak peeks at our product labs!
Tags
General Discussions
Asked by
James Legan
Top achievements
Rank 1
Answers by
James Legan
Top achievements
Rank 1
Ralph Waldenmaier
Telerik team
Share this question
or