Search code examples
c#.netunit-testingmstesttestcontext

Cannot access Properties value in MSTest


I'm actually facing an issue using TestContext in MSTest. When I add a property to the context, it doesn't exist when I try to get it in another test method. Can someone explain me why or know how to fix it? Here is my code sample:

I can't get why i can Console.Writeline the value I need in Action1() but can't access it in Action2()

Thanks :)

namespace API.Tests.Controllers
{
    [TestClass]
    public class ControllerTests
    {
        private SomeController _controller;
        private SomeService _somService;
        public TestContext TestContext { get; set; }

        [TestInitialize]
        public void Initialize()
        {
            _someService = new SomeService();
        }

        [TestMethod]
        public void Action2()
        {
            // Arrange
            var criteria = TestContext.Properties["id"]; <-- Can't access value here, it doesn't exist

            SomeController _controller = new SomeController(_someService);

            // Act
            IHttpActionResult result = _controller.Search((string)criteria);

            // Assert
            var contentResult = result as OkNegotiatedContentResult<List<Object>>;

            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result,typeof(OkNegotiatedContentResult<List<Object>>));
        }

        
        [TestMethod]
        public void Action1()
        {
            // Arrange
            var testObj = new Obj
            {
                id = 10,
                name = "Test",
                code = "XXX"
            };

            SomeController _controller = new SomeController(_someService);

            // Act
            IHttpActionResult result = _controller.Create(testObj);

            // Assert
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(OkNegotiatedContentResult<int>));

            var content = result as OkNegotiatedContentResult<int>;

            TestContext.Properties.Clear();
            TestContext.Properties.Add("id", content.Content.ToString());

            Console.WriteLine(TestContext.Properties["id"]); <-- I can get the value here
            Console.WriteLine(TestContext.Properties.Count); <-- equal to 1
        }
    }
}


Solution

  • Coupling tests is a really bad idea and introduces many problems that are hard to find. In particular you cannot execute Action2 without executing Action1, as you already noticed.

    However it's not entirely clear what your SuT is supposed to do and what you want to test. It seems your test is some integration-test that verifies a specific sequence of calls to your service-endoints. So your endpoints depend on one another in some way. Instead of splitting those calls into different tests, you can just create a single test and call your actions there. In your case it seems you want to test if you can search a resource that you created before using the Search- and Create-endpoint respectivly. So just use a single test that calls both those endpoints.

    [TestMethod]
    public void Action1()
    {
        // Arrange
        var testObj = new Obj
        {
            id = 10,
            name = "Test",
            code = "XXX"
        };
    
        SomeController _controller = new SomeController(_someService);
    
        // Act
        IHttpActionResult result = _controller.Create(testObj);
    
        // Assert
        Assert.IsNotNull(result);
        Assert.IsInstanceOfType(result, typeof(OkNegotiatedContentResult<int>));
    
        var content = result as OkNegotiatedContentResult<int>;
    
        // Act
        IHttpActionResult result2 = _controller.Search(content.Content.ToString());
    
        // Assert
        var contentResult = result2 as OkNegotiatedContentResult<List<Object>>;
    
        Assert.IsNotNull(result2);
        Assert.IsInstanceOfType(result2, typeof(OkNegotiatedContentResult<List<Object>>));
    }
    

    If this is more some unit-test, you should consider to fake the dependency, e.g. by mocking the creation of the resource and then call the Search-endpoint on that fake-instance. However I'd argue mocking your SuT is also a bad idea and often shows that it is doing to many things.