views:

180

answers:

5

this is what I would like to be able to do.

/// <summary>
        /// Gets the session factory.
        /// </summary>
        /// <value>The session factory.</value>
        public ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
#if(NUNIT)
                     _sessionFactory = Fluently.Configure()
                        .Database(SQLiteConfiguration.Standard
                                      .UsingFile(DbFile)
                                      .ShowSql())
                        .Mappings(m =>
                                  m.FluentMappings.AddFromAssemblyOf<ForeignFormat>())
                        .ExposeConfiguration(BuildSchema)
                        .BuildSessionFactory();

#else
                    _sessionFactory = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2005
                              .ConnectionString(c => c
                                                         .Server(".\\sqlexpress")
                                                         .Database("mPort")
                                                         .TrustedConnection())
                                                         .ShowSql()
                                               )

                .Mappings(m => m
                                   .FluentMappings.AddFromAssemblyOf<ForeignFormat>())
                .BuildSessionFactory();
#endif
                }
                return _sessionFactory;

            }
        }

is it possible to #if conditional if you are running a unit test?

A: 

I would not recommend this methodology for unit testing. You should never put "test" code into a production file.

You should look into mocking objects to get the desired functionality from your BuildSessionFactory method.

Casey
+1  A: 

I'd suggest mocking the db connection instead of littering #if/#else throught your code (even if it's only in this one place).

SnOrfus
I'm aware you should mock your db for the majority of your unit tests, but how do you test actual interaction with the db? FluentNH will build a fake db from your mappings, this way I can run unit tests against a "real db" and be able to see the NHibernate queries pushed out by logForNet
A: 

You shouldn't use #if sections to separate test code from production code. You want (and NEED) to test the production code.

It probably makes more sense to make the type/configuration of the database configurable. Dependency Injection is one way to do this, and the castle frameworks you seem to be using are designed to do this easily.

Dependency Injection is a technique to decouple the code you posted from the actual implementation of the database. This means you can inject a file or completely fake database class during test time.

Sander Rijken
SQLite and fluentNH seems to generate a fake db from your mappings. I want to use the fake db for unit tests and the real db for production code. Im aware this is not best practice. I'm just looking for a way to test db interaction without using the production db
you don't need to inject a mocked db per se. It's also possible to inject the fake db like you're doing in the #if section, and inject that.
Sander Rijken
+2  A: 

#if is a compiler directive, so you'd need to compile your code differently when you're going to run tests vs. when you're going to run it "for real". You can define compiler flags in a project's build settings to do this.

But, I agree with everyone else who has suggested this isn't a good approach to take. Aside from the other issues people have mentioned, it's just going to be a pain to be constantly recompiling when you want to switch between running unit tests and running the real application.

Dependency injection or mocking would serve you much better.

John Price
A: 

Why don't you create a FakeSessionFactory in your unit tests in addition to your SessionFactory ?

In the unit tests, you pass your client class a FakeSessionFactory instance, and in your application, you provide him with a SessionFactory so that it really access the DB.

        public ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    _sessionFactory = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2005
                              .ConnectionString(c => c
                                                         .Server(".\\sqlexpress")
                                                         .Database("mPort")
                                                         .TrustedConnection())
                                                         .ShowSql()
                                               )

                .Mappings(m => m
                                   .FluentMappings.AddFromAssemblyOf<ForeignFormat>())
                .BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

        public ISessionFactory FakeSessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                     _sessionFactory = Fluently.Configure()
                        .Database(SQLiteConfiguration.Standard
                                      .UsingFile(DbFile)
                                      .ShowSql())
                        .Mappings(m =>
                                  m.FluentMappings.AddFromAssemblyOf<ForeignFormat>())
                        .ExposeConfiguration(BuildSchema)
                        .BuildSessionFactory();

                }
                return _sessionFactory;
            }
        }
philippe
Thanks... I'll look into this but I using the UnitOfWork pattern and this code behind a wrapper so its difficult to dictate the behavior I think my only solution is dependency injection