chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi! I am trying to pass a fake through some constructor injection and wire it up in each test. When I run this it doesn't seem to respect the fake when it is wrapped inside an action. Here's the test class:

[TestClass, Isolated]
public class SystemTypeServiceTests
{
    SystemTypeService service;
    SystemTypeRepository fakeSystemTypeRepository = Isolate.Fake.Instance<SystemTypeRepository>(Members.MustSpecifyReturnValues);

    public SystemTypeServiceTests()
    {
        Isolate.Fake.StaticMethods(typeof(UnitOfWork));
        Isolate.WhenCalled(() => UnitOfWork.Do(null)).DoInstead(context =>
        {
            var action = context.Parameters[0] as Action;
            action.Invoke();
        });
        service = new SystemTypeService(fakeSystemTypeRepository);
    }

    [TestMethod, Isolated]
    public void Retrieve_ValidCode_ReturnsObject()
    {
        string code = "25";
        var expected = new SystemType { Id = 1L, ClientId = 25L, Code = "25", Description = "Test Type" };
        Isolate.WhenCalled(() => fakeSystemTypeRepository.RetrieveByCode(code)).WillReturn(expected);

        var actual = service.Retrieve(code);

        Assert.AreEqual(expected, actual);
    }
}


Here's the method under test:

public SystemType Retrieve(string code)
{
    Check.ForPatternMismatch(code, SystemTypeRepository.CodeFormat, "code");

    SystemType result = null;
    UnitOfWork.Do(() =>
    {
        result = repository.RetrieveByCode(code);
    });
    return result;
}


When I comment out the UnitOfWork.Do component it returns properly with the fake, but when I put it back in it flakes.

Thoughts?
asked by colinbo (1.8k points)

4 Answers

0 votes
Hi,

I think its an old limitation that never got removed :cry:

If youre inside a doinstead block the mocking is turned off. resulting in faking not working.

As far as I know there is no work arround this, and after rereading you test im not sure exactly what you are testing.

:idea: maybe if you can explain what you are trying to test, we can find an alternative way of testing it.
answered by error (6.6k points)
0 votes
This example I used was to put the focus on the construct rather than what happens inside the action block. I am wrapping some series of steps in a transaction that will auto-commit if all goes well or rollback if an exception is thrown.

The premise that mocking is disabled doesn't make sense unless I'm missing something about how TypeMock weaves itself into the code. The delegate is nothing more than a compiler trick that creates a method at compile time. The reference of the resource (in this case the repository) points back to a field on the class, not something created inside the delegate.
answered by colinbo (1.8k points)
0 votes
Hi Colin,

Lior is correct about the limitation of the Isolator :(
Currently you can't use fakes inside the DoInstead callback.

That been said, from the code you posted it seems that you should not fake SystemTypeRepository since it will make the useless (you are faking the result you are expecting to see).
Usually you don't want to fake the code that you are testing, instead you should fake the code under test dependencies.
answered by ohad (35.4k points)
0 votes
Thanks for the response Ohad! I'll have to investigate how to restructure then. The example is a bit contrived in that there are actually other things around the retrieve call that are happening; I didn't output them because they aren't relevant to the question.
answered by colinbo (1.8k points)
...