Welcome to Typemock Answers. Here you can ask and receive answers from other community members. And if you liked or disliked an answer or thread: react with an up- or downvote Enjoy!

How can I test that an internal property was set with a specific value during a method call

+2 votes

I am trying to unit test an AspNetCore.Mvc controller with Typemock. Here is the top layer of the controller code. 

        [HttpPost(UriFactory.FOO_ROUTE)]
        public async Task<ActionResult> AddFooAsync([FromRoute]string novelid, [FromBody]AddFoo command)
        {
            var novel = await RetrieveNovel(novelid);
            if (novel == null) return NotFound();
 
            if (!ModelState.IsValid) return BadRequest(ModelState);
 
            command.FooId = Guid.NewGuid();
            novel.AddFoo(command);
            await _store.SaveAsync(novel);
            return Created(UriFactory.GetFooRoute(novel.Novel.NovelId, command.FooId), command);
        }
 
Here is the test code I've written so far..
 
    [TestClass, Isolated]
    public class FooController_UnitTests
 
        [TestMethod, Isolated]
        public async Task TestMethod()
        {
 
            //Arrange
            string novelid = "0";
            Novel controllerUnderTest = Isolate.Fake.Dependencies<Novel>();
 
            //Fake Foo
            var ValidTestFoo = Isolate.Fake.Dependencies<AddFoo>();
            
            //Fake the RetrieveNovel(novelid) call
            Isolate.NonPublic.WhenCalled(controllerUnderTest, "RetrieveNovel").WillReturn(Task.FromResult(new GenreNovel()));
 
            //Fake the ModelState
            Isolate.WhenCalled(() => controllerUnderTest.ModelState.IsValid).WillReturn(true);
 
            //Fake FooId
            Isolate.NonPublic.Property.WhenGetCalled(ValidTestFoo, "FooId").WillReturn(Guid.NewGuid());
            
            //Act
            var fooResponse = controllerUnderTest.AddFooAsync(novelid, ValidTestFoo);
 
            //Assert
            //that RetrieveNovel(novelid) is called 
            Isolate.Verify.NonPublic.WasCalled(controllerUnderTest, "RetrieveNovel");
 
            //that (!ModelState.IsValid) is called
            Isolate.Verify.WasCalledWithAnyArguments(() => controllerUnderTest.ModelState.IsValid);
 
            //that command.FooId was set with a Guid.NewGuid();
            Isolate.Verify.NonPublic.Property.WasCalledSet(ValidTestFoo, "FooId").WithArgument(Guid.NewGuid());
}
}

FooId is an internal property of AddFoo. Right now I am trying to test that the FooId was set as a consequence of the AddFooAsync method logic, AND that it was set with a Guid.NewGuid.

My other 2 Verifies are passing but when I run the test with the last verify I get ....

  TypeMock Verification: Property blahblahblah was called with mismatching arguments.
 
Thanks! 
asked Oct 25 by wayne (220 points)

1 Answer

+2 votes
 
Best answer

In the test try creating:

var newGuid = new Guid();

and pass it in the verification:

 Isolate.Verify.NonPublic.Property.WasCalledSet(ValidTestFoo, "FooId").WithArgument(newGuid);

 

answered Oct 25 by Raphy (2,440 points)
selected Oct 26 by wayne
Thanks Raphy but I get the same error. I'm guessing that it's comparing the actual value of the Guid.NewGuid that's getting generated in the controller logic to the Guid that I'm generating in the test and seeing that they are not the same. Is there a way in TypeMock that I can test that the value of FooId was set to  <T> Guid instead of comparing the actual values of the Guid? I think that will accomplish what I'm trying to do, just verifying that it got set to a Guid.

What you can do is:

Extract the property with:

var fooID = Isolate.Invoke.Method(c, "get_FooID");

and assert that it's a Guid:

Assert.IsTrue(fooID is Guid);

 

Thank you Raphy. That worked, but then I noticed that I was explicitly assigning a Guid to FooId in my test logic. When I disabled that, the test failed. But when I went back and changed..

Isolate.NonPublic.Property.WhenGetCalled(ValidTestFoo, "FooId").WillReturn(Guid.NewGuid());

to...

Isolate.NonPublic.Property.WhenGetCalled(ValidTestFoo, "FooId").CallOriginal();

it gave me the behavior I was expecting.

Thanks for your help! 

I'm glad the test is stable and working for you.

As you sent only a part of the code, I don't see where you invoke the "ValidTestFoo.get_FooId" within your code, so I can't say why it broke before the change.

You can try and debug it or use the Typemock Insight to track all the faked objects and methods and see why it broke.

If the change maintains the logic of the behavior you wish to test then keep it. :)

...