I'm trying to use NUnit TestAttributes to create and delete a RestSharp RestClient
https://github.com/nunit/docs/wiki/TestFixture-Attribute
using NUnit.Framework;
using RestSharp;
namespace Sanitized.Sanitized.Steps
{
[TestFixture]
public class SetupAndTeardown
{
public RestClient restClient;
[SetUp]
public void Init()
{
restClient = new RestClient();
}
[TearDown]
public void Cleanup()
{
restClient = null;
}
}
}
But, I get the error Object reference not set to an instance of an object. when trying to use this in another class i.e. with my automated steps.
I don't understand this, as I thought code that's in the [SetUp] [Teardown] attributes are called at the beginning and end of the test respectively.
You created a TestFixture, which is a class that contains tests. If the fixture had any tests, then NUnit would run them and would also run the setup before each test and the teardown after each test. Since you have no tests, that isn't happening. NUnit recognizes the fixture but finds nothing to run there.
You say that you have a problem when you "use" this fixture in another class. Test fixtures are not intended to be "used" by other code. Rather, they are run by NUnit.
For a better answer about how to do what you are trying to do, we first need to know what you are trying to do. When do you want the "setup" and "teardown" to run? How often should they run? Depending on those things, I can update this answer.
Replying further to your comment... If your tests are in another class, then that class is your test fixture. Is there a reason you don't want it to be the fixture?
Related
I have a solution that contains a unit test project. I'm using NUnit v3.10.1 and NUnit3TestAdapter v3.10.0.
Is there a way to configure how the test names are displayed in Visual Studio Team Services (VSTS), maybe displaying the test class name? At the moment it displays only the test name:
It's hard to understand which test belongs to which class. In this case, I have at least 2 test classes that have the same test names.
Running the same tests using Reshaper's test runner it's quite easy to understand which tests belong to which classes:
I have tried settings the TestName of the TestFixture Attribute attribute or setting the Description of the Test Attribute with no luck:
[TestFixture(TestName = "MemoryCacheManagerTests_TryGetItem", TestOf = typeof(MemoryCacheManager))]
public class MemoryCacheManagerTests_TryGetItem : MemoryCacheManagerTests
{
[Test(Description = "MemoryCacheManagerTests_TryGetItem_WithInvalidCacheKey_ShouldThrowArgumentException")]
[TestCaseSource(typeof(InvalidCacheKeyTestCases))]
public void WithInvalidCacheKey_ShouldThrowArgumentException(string key)
{
// ...
}
}
So how do I configure the names of the tests on VSTS?
No, there's no way to configure it. You can submit a UserVoice item to suggest product improvements.
I have an issue in where my [AssemblyCleanup] method is not being called.
I'm currently building out an automation framework and would like some API calls done before and after my tests. I've since found the assembly initialize/cleanup methods, and they would work perfect for what I need to do. But I am unable to to get the [AssemblyCleanup] method to run.
I have a base class that my tests inherent from, and that's where I'd like the [AssemblyCleanup] method to be placed.
My class.
[TestClass]
public class TestBaseChrome: WebDriver
{
public TestContext TestContext { get; set; }
[TestInitialize]
public void Initialize()
{
//Do Stuff Here for tests
}
[TestCleanup]
public void Cleanup()
{
//used for end of test reporting
}
[AssemblyCleanup]
public static void EndOfSuiteActions()
{
//Stuff here when whole test suite finished
}
}
I've seen the examples here and here and show that the [AssemblyCleanup] needs to be in a class with the [TestClass] attribute. If I place the [AssemblyCleanup] in a class with actual tests, it works as intended. But I'd like all my before tests/after tests in once place.
Any advice would be appreciated.
I believe I've found the answer to my own question.
If a [TestClass] inherits from a base class that is in a different assembly of the derived class, the base class [AssemblyInitialize] and [AssemblyCleanup] methods are not executed.
Source
So as my automation tests are in two projects in the solution (one to handle the framework and one to handle the tests) and as the base class is in the framework, but the tests are the other project. I encounter the issue in the link.
I've got a controller with a lot of constructor injection:
public MoviesController(ISession session, IClientContext clientContext, PManager pManager, ISegmentationService segmentationService, IGeoLocator geoLocator, IBus bus)
{
_session = session;
_clientContext = clientContext;
_pManager = pManager;
_segmentationService = segmentationService;
_geoLocator = geoLocator;
_bus = bus;
}
From my understanding (just read about Mocking), I've got a lot of Mock object properties to manually set if I wish to make a comprehensive test suite based on this controller.
For one method I'm only using one service (I'd even like to automate that with little effort if possible):
public object Show(Guid id)
{
var movie = _session.Get<movie>(id);
return movie;
}
But in another there are many services being used - is there any way to set those Moq objects up quickly? I could really use some examples as I'm new to testing. It's an asp.net mvc project with webapi 1 bundled in (testing the webapi controller here)
As has been said in the comments, if you have common setup code, you can put it in a Setup method that is called automatically from your testing framework before each test. It's decorated with a Setup attribute if you're using Nunit TestInitialize if you're using MStest. If you're using XUnit then it's a bit different.
So, your class might look like this:
public class SomeTests {
Mock<ISession> _sessionMock;
Mock<IClientContext> _clientContextMock;
[Setup]
public void Setup() {
_sessionMock = new Mock<ISession>();
_clientContextMock = new Mock <IClientContext();
}
MovieController CreateSut() {
return new MovieController(_sessionMock.Object, _clientContextMock.Object, ...);
}
[Test]
public void TestSomething() {
_sessionMock.Setup(x=>...);
//...
var sut = CreateSut();
//...
}
}
If you're trying to get away from completely creating the mocks manually, then you might want to look at something like AutoFixture with AutoMoq. Which will automatically supply mock instances when creating objects that accept interfaces. AutoFixture can be quite useful, but there is a learning curve to using it effectively so you might want to look at a tutorial / quickstart.
You could also configure an IOC container to supply mock instances for your test project, although I've never gone down that route myself.
For your example, you only need to mock the session, and can leave all the other dependencies null, since their behaviour should be irrelevant to the behaviour you are testing:
Mock<ISession> mockSession = new Mock<ISesssion>();
MoviesController controller = new MoviesController(mockSession.Object, null,null,null,null,null);
There is no need for you to set up any mocks other than the ones you need for this particular test
I am trying to structure my unit test in such a way that if I change the constructor of the object being tested I don't have to change a lot of tests. Here is a simplified example of my set up right now:
[TestMethod]
public void Test1()
{
_mockedObject1.Setup(etc);
_mockedObject2.Setup(etc);
var service = new TestedService(_mockedObject1.Object, _mockedObject2.Object, ...,
_mockedObject7.Object);
//Act and Assert
}
Now I've got 20 unit tests that are arranged this same way. If I have to change the constructor of TestedService I have to go into all 20 tests and change the line that creates service. Can I pull this line of code out into TestInitialize or something so that I would only have to change it one time? My first thought is that I can't because then service would get created before my .Setups. Is there another way to handle this?
Yes, you can pull the creation of your service before setting up the dependencies. The SetUp will still be bound to the mocked objects. You could try something like:
private TestedService service;
[SetUp]
public void SetUp()
{
this.service = new TestedService(_mockedObject1.Object, _mockedObject2.Object, ...,
_mockedObject7.Object);
}
[TestMethod]
public void Test1()
{
_mockedObject1.Setup(etc);
_mockedObject2.Setup(etc);
//Act and Assert
this.service.Whatever(...);
}
Take a look at Automoqing since you are already using Moq it would do what you want or even better. Simply it is Dependency Injection container that injects mocks.
You can initialize these objects in the function with a [ClassInitialize()] attribute. This is supposed to run before any tests within that class run.
I'm trying to test my service using ninject and an unit test project with visual studio 2012. My inject works ok on my controllers, but when I try to do the same in the unit test class I get an Exception.
System.NullReferenceException: Object reference not set to an instance of an object.
namespace Trex.UnitTests
{
[TestClass]
public class GiftServiceTests
{
private IGiftService _giftService;
public void GiftServiceTest(IGiftService giftService)
{
_giftService = giftService;
}
[TestMethod]
public void AddGift()
{
var list = _gift.FindAll(); <--- this line throw an exception
}
}
}
I think there is something wrong with the injection but I dont get it.
It looks to me like a typo of _giftService. In addition, attribute [TestInitialize] needs to be used in your constructor.
Try the following code by placing the correct service name _giftService - that your code is injecting instead:
var list = __giftService.FindAll();
Edit: Unit testing should be done without Ninject. Just create an instance of the object under test and inject a mock for every dependency manually.
Here is a sample with [TestInitialize]:
The unit test must have a default constructor:
[TestClass]
public class TestControllersHomeController
{
private HomeController _sut;
[TestInitialize]
public void MyTestInitialize()
{
var kernel = NinjectWebCommon.CreatePublicKernel();
_sut = kernel.Resolve<HomeController>();
}
[TestMethod]
public void TestIndex()
{
var result = _sut.Index();
Assert.IsNotNull(result);
}
}
The only way dependency injection is able to call your constructor and fill it with a parameter that has a value is if the dependency injection kernel is the one that instantiates your class.
In your case, MSTest is instantiating your test class, so Ninject does not have a chance to call your constructor.
To be honest, you are going about this the wrong way. You will battle MSTest if you pursue this further to try to get Ninject (or any other DI framework) to instantiate your test classes.
I would recommend you use 'new' to instantiate the class under test (_giftService = new GiftService();). If that class has dependencies in its constructor, use a mocking framework to pass in mocked version of those dependencies. This way you isolate your unit tests to only the functionality of the class under test.
_gift is null. Your variable is _giftService. You also should use the [TestInitialize] attribute for your constructor.
Extra tip:
You shouldn't create any dependencies in your unit test. So the giftService which you want to use should be a mock or a stub.