I have the following code for which I am writing a unit test
protected virtual string GetTokenFromTheWebrequest(WebRequest httpWebRequestObject)
{
try
{
HttpWebResponse responseHttpPostForToken = (HttpWebResponse)httpWebRequestObject.GetResponse();
string tokenJson = GetContentResponse(responseHttpPostForToken);
AccessToken accesstokenObj = DeserializeToAccessToken(tokenJson);
return accesstokenObj.Token;
}
catch (Exception Error)
{
Log.Debug("error");//I want to test this method
throw Error;
}
}
So,For this I have this unit test
[Test]
[ExpectedException(typeof(JsonReaderException))]
public void GetTokenFromTheWebrequestTestwithInValidHttpWebResponseOjectJsonReader()
{
var mockHttpWebResponse = new Mock<HttpWebResponse>();
var mockHttpWebRequest = new Mock<HttpWebRequest>();
var mockLog = new Mock<ILog>();
mockHttpWebRequest.Setup(c => c.GetResponse()).Returns(mockHttpWebResponse.Object);
mockedSurveyMonkeyAPIService.Setup(y => y.GetContentResponse(mockHttpWebResponse.Object)).Returns(TestData.TestData.SampleResponseStream);
mockedSurveyMonkeyAPIService.Setup(z => z.DeserializeToAccessToken(TestData.TestData.SampleResponseStream)).Throws(new JsonReaderException());
//mockLog.Setup(x => x.Debug("error")).Throws(new WebException());
var token = mockedSurveyMonkeyAPIService.Object.GetTokenFromTheWebrequest(mockHttpWebRequest.Object);
mockLog.VerifySet(x => x.Debug("error"),Times.Once); //its not going till this when i debug
}
Can anyone suggest how to check whether Log.Debug is called properly.
You don't seem to be testing any of your own code... you've mocked pretty much everything being used in that method. This begs the question what is actually being tested and the answer is that your implementation details are being tested, not any logic. You have even mocked the logger, so really you are testing the .NET try-catch mechanism here.
If you make any minor change to this method, your test will break even though the behaviour is the same. This is not the kind of test you want to shackle yourself to.
There are better ways of testing. For example, if you want to test your logger - test it in isolation of this method so you know your logger works. Don't test the logger by testing calls to it everywhere it is used.
Related
Sorry, this is likely a very amateur question, but I am struggling to understand how to use Moq properly. I am quite new to unit testing as a whole, but I think I'm starting to get the hang of it.
So here's my question... I have this snippet of code below which is using a TestServer in Visual Studio that I using for am Unit Testing... I'm trying to mock IGamesByPublisher so that my test is not reliant on data in the repository (or would it be better to mock GamesByPublisher?... Or do I need to do both?)
public static TestServerWithRepositoryService => new TestServer(services =>
{
services.AddScoped<IGamesByPublisher, GamesByPublisher();
}).AddAuthorization("fake.account", null);
[Fact] // 200 - Response, Happy Path
public async Task GamesByPublisher_GamesByPublisherLookup_ValidRequestData_Produces200()
{
// Arrange
var server = ServerWithRepositoryService;
// Act
var response = await server.GetAsync(Uri);
// Assert
Assert.NotNull(response);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
Here is the IGamesByPublisher
public interface IGamesByPublisher interface.
{
Task<IEnumerable<Publisher>> Execute(GamesByPublisherQueryOptions options);
}
}
I tried
public static TestServerWithRepositoryService => new TestServer(services =>
{
services.AddScoped<Mock<IGamesByPublisher>, Mock<GamesByPublisher>>();
}).AddAuthorization("fake.account", null);
And then I tried
// Not exactly what I attempted, but that code is long gone...
var mock = new Mock<IGamesByPublisher >();
var foo = new GamesByPublisherQueryOptions();
mock.Setup(x => x.Execute(foo)).Returns(true);
I didn't really find great documentation on using Moq, just the quick start guide on GitHub, which I wasn't sure how to apply (probably my own level of experience at fault there...).
I am obviously missing some fundamentals on using Moq...
You were close.
public static TestServerWithRepositoryService => new TestServer(services => {
var mock = new Mock<IGamesByPublisher>();
var publishers = new List<Publisher>() {
//...populate as needed
};
mock
.Setup(_ => _.Execute(It.IsAny<GamesByPublisherQueryOptions>()))
.ReturnsAsync(() => publishers);
services.RemoveAll<IGamesByPublisher>();
services.AddScoped<IGamesByPublisher>(sp => mock.Object);
}).AddAuthorization("fake.account", null);
The above creates the mock, sets up its expected behavior to return a list of publishers any time Execute is invoked with a GamesByPublisherQueryOptions.
It then removes any registrations of the desired interface to avoid conflicts and then registers the service to return the mock any time the interface is requested to be resolved.
I've noticed that NUnit's TestContext.CurrentContext.Result.Outcome.Status is always Inconclusive at the end of a test run. The CurrentContext is also unaware that any assertions have taken place.
Is it possible to get the status of a test before the [TearDown]?
I was hoping to use the value during the Dispose() of my test management class to capture metrics and other data for post-test diagnosis.
Code example from a new .NET Framework 4.6.1 project that only has the NuGet packages NUnit and FluentAssertions:
namespace TestProject
{
using FluentAssertions;
using NUnit.Framework;
[TestFixture]
public class Class1
{
[Test]
public void test1()
{
var a = 1;
var b = 2;
var c = 1;
var context = TestContext.CurrentContext;
a.Should().Be(c);
Assert.AreEqual(a, c);
}
}
}
A test result starts out as Inconclusive. If the test is skipped or ignored, then the result changes, but of course it is never executed.
If it is executed, the Outcome is Inconclusive until the test is over. Clearly, while you are still executing the test, it is not yet finished. When teardown begins, the outcome of the test is known, so it will vary according to whether the test method itself was successful. Of course, an exception in teardown may change the result to an Error state.
Bottom line, the Outcome field is not useful while the test method itself is still running. In any case, if you are executing code in the test method, the test has not yet failed. Otherwise, you would not have continued execution!
You say you can't use TearDown but the link you provide doesn't deal with the issue of accessing the test result. Can you explain further? What exactly do you want to do after checking the test result?
You could try using AssertionScope along with the AssertionScope.Succeeded flag. Although the intelisense on that property specifies:
Gets a value indicating whether or not the last assertion executed through this scope succeeded.
Example usage of AssertionScope
[Test]
public void Test()
{
var a = 1;
var b = 2;
var c = 1;
var context = new AssertionScope();
try
{
throw new Exception("Test");
}
catch (Exception e)
{
context.FailWith(e.ToString());
}
var strings = context.Discard();
Console.WriteLine(strings.StringJoin(","));
context.Succeeded.Should().BeFalse();
var someOtherContext = new AssertionScope();
try
{
c.Should().Be(a);
}
catch (Exception e)
{
someOtherContext.FailWith(e.ToString());
}
var discard = someOtherContext.Discard();
Console.WriteLine(discard.StringJoin(","));
someOtherContext.Succeeded.Should().BeTrue();
}
To clarify what I'm trying to do, I have a method that creates/updates an item in my DB. When Testing as usual by asserting that the item is in the in-memory database always comes back as null. After reading the docs, it appears I need to be determining whether or not the correct job has been added to the Hangfire queue.
I've been going over the documentation for unit testing a Hangfire implementation but can't seem to find a way to test against in-memory storage.
In the example, a mock is created and then passed into the constructor of the controller. However, I've been modeling my solution after this example where jobs are queued in the Configure method of the Startup class. This means I have no controller and I'm not passing anything into my methods that are queuing up my jobs.
So how should I be going about testing this?
Here's one of the methods I'm trying to test:
public async Task SyncDeletedAccounts()
{
try
{
int pastMinutes = 90;
var startDate = DateTime.Now.AddMinutes(0 - pastMinutes);
var client = await this._forceDotComService.GetForceClient();
var deletedIds = await this._forceDotComService.GetDeletedIds<sf.Account>(client, startDate);
if (!deletedIds.Any())
{
this._logger.LogInformation("No deleted accounts");
return;
}
foreach (var deletedId in deletedIds)
{
BackgroundJob.Enqueue<InterconnectorServiceHelper<sf.Account, ic.Account>>(i =>
i.MarkDeleted(deletedId));
}
}
catch (Exception e)
{
this._logger.LogError(e, "AccountService.SyncDeletedAccounts");
throw;
}
}
I'm trying to become more familiar with the Rhinomocks framework, and I'm trying to understand the Expect methods of rhinomocks.
Here's a unit test I have written:
[TestMethod]
public void Create_ValidModelData_CreatesNewEventObjectWithGivenSlugId()
{
//Arrange
var eventList = new List<Event>() { new Event() { Slug = "test-user" } };
_stubbedEventRepository.Stub(x => x.GetEvents())
.Return(eventList);
_stubbedEventRepository
.Expect(x => x.SaveEvent(eventList.SingleOrDefault()))
.Repeat
.Once();
var controller = new EventController(_stubbedEventRepository);
EventViewModel model = new EventViewModel();
//Act
//controller.Create(model); COMMENTED OUT
//Assert
_stubbedEventRepository.VerifyAllExpectations();
}
I thought I understood this code to only pass if the SaveEvent(...) method get's called exactly once. However, with controller.Create(model) commented out, the test still passes. Inside controller.Create(model) is where the SaveEvent() method gets called.
I tried the following:
_stubbedEventRepository
.Expect(x => x.SaveEvent(eventList.SingleOrDefault()));
But it still passes every time, so what am I doing incorrectly stack overflow? The sources I have looked at online haven't been able to help me. Why is VerifyAllExpectations() yielding a successful unit test?
Thank you!
Here's the body of the controller constructor:
public EventController(IEventRepository eventRepository)
{
_eventRepository = eventRepository;
}
edit:
// member variables
private IEventRepository _stubbedEventRepository;
[TestInitialize]
public void SetupTests()
{
_stubbedEventRepository = MockRepository.GenerateStub<IEventRepository>();
}
If you want to verify the behavior of the code under test, you will use a mock with the appropriate expectation, and verify that. If you want just to pass a value that may need to act in a certain way, but isn't the focus of this test, you will use a stub.
I'm unit testing a demo application, which is a POP3 client. The POP3 client implements IDisposable, so I'm trying to test a using cycle.
(I'm using nunit 2.5.2 and Moq 4.0)
/// <summary>
/// Unsuccessful construct dispose cycle, no ILogger object given.
/// Expecting ArgumentNullException. Expecting TcpClient dispose to be called.
/// </summary>
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ConstructorDispose_LoggerNull_ArgumentNullException()
{
mockTcpClient.Setup(x => x.Dispose());
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
mockTcpClient.VerifyAll();
}
As you can see the verifyAll method will never be invoked and the test will be successful, nonetheless. So ...
What is the best way to solve this?
Is there another way then try catch?
Update I fixed it like this for the moment:
mockTcpClient.Setup(x => x.Dispose());
var correctExceptionThrown = false;
try
{
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
}
catch (ArgumentNullException)
{
correctExceptionThrown = true;
}
finally
{
mockTcpClient.VerifyAll();
}
Assert.That(correctExceptionThrown);
But dispose isn't called, seems to be the C# specification.
mockTcpClient.Setup(x => x.Dispose());
try
{
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
}
finally
{
mockTcpClient.VerifyAll();
}
This doesn't answer your question (as it's already solved), but it's relevant and worth posting anyway.
[ExpectedException] is a pretty ropey way to test exceptions. It can be error prone, as the wrong line can trigger an exception of the expected type resulting in an erroneous pass. I would strongly advocate that you check out Assert.Throws() instead :)
It's nicer to use (you can query the returned exception), more readable and, above all, safer.
You can find an example here
You have already discovered that dispose really is not supposed to be called if the constructor fails. But there may still be other cases where you might want to to verify your mocks after an expected exception is thrown. I just do that in the test TearDown like this:
[SetUp]
public void SetUp()
{
this.mockFactory = new MockFactory(MockBehavior.Loose);
}
[TearDown]
public void TearDown()
{
this.mockFactory.VerifyAll();
}
[Test]
[ExpectedException(typeof(NoBananasException))]
public void EatThrowsIfNoBananasAvailable
{
var bananaProvider = this.mockFactory.Create<IBananaProvider>();
bananaProvider.SetUp(bp => bp.IsBananaAvailable).Returns(false).Verifiable();
var monkey = new Monkey(bananaProvider.Object);
monkey.Eat();
}
You seem to be testing that the injected mockTcpClient instance is disposed even if the constructor throws an exception, in which case this should work:
mockTcpClient.Setup(x => x.Dispose());
try
{
var popClient= new PopClient(null, mockTcpClient.Object);
}
finally
{
mockTcpClient.VerifyAll();
}
EDIT: Actually, try/finally would be cleaner than catching Exception. Note that you don't need to dispose popClient since no instance is created.