2

I am new to unit testing and mocking. The project I am working on has many methods that look like this:

public bool MyMethod(int param, int param2)
{
    using (SomeEntity dBcontext = new SomeEntity())
    {
        FancyObj theobj = dBcontext.MyObjs.FirstOrDefault(l => l.ObjId == param2);
        if (theobj != null && theobj.CurrentSeason != param) //if season has changed then update
        {
            theobj .CurrentSeason = param;
            dBcontext.SaveChanges();

            return true;
        }
        return false;
    }
}

I am using Telerik JustMock and unless I am missing something, there is no way for me to Mock the entity call since its being instantiated directly within the method in test.

Is my only solution to modify the method/class to hold a property of type SomeEntity?

TacticalMin
  • 791
  • 2
  • 7
  • 18

4 Answers4

2

Newing up an instance of required dependency (instead of asking for it in the constructor) kills testability. Essentially, by using new operator, you are mixing the concern of application instantiation with concern of application logic.

Dependency injection to the rescue! Your class under test should ask for all the things required to get its job done in the constructor and rely on interfaces, not the concrete implementations. That way, you will be able to provide fake implementations to make your unit test fully isolated.

Sergey Kolodiy
  • 5,829
  • 1
  • 36
  • 58
1

Without refactoring your code I think you may be out of luck with conventional mock frameworks, since all Mock Frameworks depend on methods being either virtual or an interface.

But if you own Visual Studio Premium or Ultimate edition you may use Microsoft Fakes which allow you modify/replace/intercept calls to non-virtual methods and properties (works by modifying/injecting CIL code into that 3rd assemblies when they are loaded).

Tseng
  • 61,549
  • 15
  • 193
  • 205
1

Whilst Dependency injection is probably the better way to go in the long term (it'll typically improve the structure of your code), there are commercial solutions like Typemock that allow you to test code that can't be tested in a conventional way. This is a bit of a mixed blessing, as you can become dependant on the mocking framework and don't necessarily reap the structural changes that can be encouraged by unit testing with more traditional mocking frameworks. However it should allow you to test the situation you're describing.

An example from their website shows how they are able to get a handle to the object created within their Calculate function. As is illustrated in some of their other examples, this handle can then be used to setup expectations on the calls to that dependency:

public static int Calculate(int a, int b)
{
   var dependency = new Dependency();
   dependency.CheckSecurity("typemock", "rules");
   return a + b;
}

[TestMethod,Isolated]
public void FakeConstructor()
{
    // Fake the Dependency constructor
    var fakeHandle = Isolate.Fake.NextInstance<dependency>();
    var result = ClassUnderTest.Calculate(1, 2);
    Assert.AreEqual(3, result);
}

There are various different pricing options and I'm not sure what you get for each tier, however if you really don't want to change your code and you have fairly deep pockets it may be worth considering.

forsvarir
  • 10,749
  • 6
  • 46
  • 77
0

Yes, it is possible to arrange the return value of a new expression using the commercial version of JustMock.

var mock = Mock.Create<SomeEntity>();
Mock.Arrange(() => new SomeEntity()).Returns(mock);

From here on you can arrange the mock to have the behavior you need for the test. If you're using EF6, then you can try Telerik.JustMock.EntityFramework that plugs into JustMock to create in-memory mock DB contexts for your tests.

Stefan Dragnev
  • 14,143
  • 6
  • 48
  • 52