DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Securing Your Software Supply Chain with JFrog and Azure
Register Today

Trending

  • Microservices With Apache Camel and Quarkus (Part 2)
  • Health Check Response Format for HTTP APIs
  • What ChatGPT Needs Is Context
  • Operator Overloading in Java

Trending

  • Microservices With Apache Camel and Quarkus (Part 2)
  • Health Check Response Format for HTTP APIs
  • What ChatGPT Needs Is Context
  • Operator Overloading in Java
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. NUnit, Unity Dependency Injection, MOQ and Private Fields

NUnit, Unity Dependency Injection, MOQ and Private Fields

Dave Bush user avatar by
Dave Bush
·
Oct. 28, 14 · Interview
Like (0)
Save
Tweet
Share
6.72K Views

Join the DZone community and get the full member experience.

Join For Free

i had an interesting puzzle to solve this week that i thought i would share with you in case someone else is looking for a similar solution.

there was some code that i needed to test that ultimately called into the database. since this is a unit test and all i was interested in testing was one specific function and the state of one specific field in another  object, i had neither the need, nor the desire, to let that call to the database happen.  since moq is  my mocking framework of choice, i wanted to mock out the database object the method was using so that it would return whatever was expected without actually calling down into the database.

there were several problems.  the first was that the database object is a private field in the class i was testing and it got created by the constructor.  second, the code that needed to use the database object is passing the object by reference (using the “ref” keyword) so that i could no setup my class that needed that object to just ignore it.

there were some other items i needed to inject, but they were pretty straight forward.

disclaimer

but first, i realize that some purist out there is going to leave me a comment that says you shouldn’t use a dependency injection container in your unit test.  my answer to that is, yes, ideally, one should not do this.  but, not everything is ideal.  not every project is a “green field” project (and in fact about 95% of them aren’t).  and in some cases there is so much technical debt involved that the best we can do is a hack.  read, working effectively with legacy code for other illustrations of “hacks” to get code under test.

so, there’s the problem.  it may not make a lot of sense yet, especially if you are not familiar with the tools.  so let’s walk through some code.

the code

the main method i wanted to test was hanging off a poco class.  it is using what we call a “visitor” pattern (though i’m pretty sure this is not what the pattern is supposed to look like).  so we have an accept() method hanging off of it that knows how to store the poco into the database.

that method has a method it calls that hangs off a crud object called create() that takes the poco and a reference to the database.

i want to mock the create() method so that it never actually gets called.  the method should return the poco as part of a list of the poco’s type.

mocking out the crud object is pretty straight forward:

_mockcrud = new mock<icrud>()

and then registering it with the unity di container:

container.registerinstance(_mockcrud);

the real issue, and the main point of this post, is that when i wanted to call create() what i needed to do was:

_mockcrud.setup(
    x => x.create(it.isany<ipocotype>(), 
        ref it.isany<idatabasetype>())
    .returns(pocolist);

which you can’t do.

what you have to do instead is:

_mockcrud.setup(
    x => x.create(it.isany<ipocotype>(),
        ref _database))
    .returns(pocolist);

and the only way this will work is if the _database variable is pointing to the same object that will ultimately get called.

so, here is the magic that i used to make all that work.

reflection.

the database object i needed was created as part of the constructor in yet another object that i pass into the accept() method.  so, i create that object and then use reflection to get the instance of the database from it.

var visitor = new datavisitor();
var fieldinfo = visitor.gettype()
    .getfield("_database",
        bindingflags.nonpublic | bindingflags.instance);
if(fieldinfo != null)
{
    _database = (database)fieldinfo.getvalue(visitor);
}

and now i can use the setup code i’ve already specified.

hope that helps someone else.

Dependency injection Database Object (computer science) unit test unity Game engine NUnit

Published at DZone with permission of Dave Bush, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Microservices With Apache Camel and Quarkus (Part 2)
  • Health Check Response Format for HTTP APIs
  • What ChatGPT Needs Is Context
  • Operator Overloading in Java

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: