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
}
}
}
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.