I'm trying to perform a Unit testing on a controller method as below,
[TestFixture]
public class HomeControllerTests
{
static object[] TestData =
{
new object[] { new EmployeeAgreementRequest(), 1, 4 }
};
[Test, TestCaseSource("TestData")]
public void AgreetoParticipate(EmployeeAgreementRequest employeeAgreementRequest, int brandID, int employeeID)
{
HomeController controller = new HomeController();
IHttpActionResult actionResult = controller.AgreeToParticipateInSP(employeeAgreementRequest, brandID, employeeID);
var contentResult = actionResult as OkNegotiatedContentResult<Boolean>;
NUnit.Framework.Assert.IsNotNull(contentResult.Content);
NUnit.Framework.Assert.AreEqual(true, contentResult.Content);
}
}
This method is not getting picked up, when i say debug tests. Please let me know what am i missing here.
Also please let me know if this the right way to run test method with multiple test data.
Visual studio output:
No tests found to run.
The form of your source data is incorrect. A field marked with [TestCaseSource] is expected to contain an IEnumerable with each enumerated item forming a test case. In your code, the object[] provides the enumeration and contains three separate test cases with one argument each. Obviously that's not your intent, you only have one test case with three arguments.
If you were using a different runner, e.g. the console runner, you would see an error message for this. Because of how the Test Explorer works, you don't see one there although there is probably a log message from NUnit in the output window.
The correct form for your test case would be as follows:
static object[] TestData = new object[]
{
new object[] { new EmployeeAgreementRequest(), 1, 4 }
};
or alternatively...
static TestCaseData[] TestData = new TestCaseData[]
{
new TestCaseData( new EmployeeAgreementRequest(), 1, 4)
};
IMO, the second is much clearer to anyone reading your code.
Related
Before starting, I have used Moq to mock things in unit tests for years. This should be a simple mock verify, but for whatever reason moq is not matching the invocation on the Mock when it occurs. I've manually tested, it is hit. I've debugged the test and compared actual vs. expected values (they match), I've scoured SO and its multitudes of people doing blatantly wrong things and I cannot figure out why this isn't working. Help appreciated.
The unit test is a very simple test of checking if BulkInsert is called at the end of a void returning function. Sample code:
Code:
public interface IDependencyService
{
void BulkInsert(IList<T> items);
}
public class MyServiceClass
{
private readonly IDependencyService _service;
/* ctor and all that jazz */
public void Run()
{
/* do things to the data */
_service.BulkInsert(items); // where items is an IList<T>
}
}
Test:
public class ServiceTests
{
[Fact]
public void ServiceRun_Calls_DependencyBulkInsert()
{
var dependencyMock = new Mock<IDependencyService>();
List<T> expected = /* somehow build expected values */
dependencyMock
.Setup(mock => mock.BulkInsert(It.IsAny<IList<T>>()));
var sut = new MyServiceClass(dependencyMock.Object);
sut.Run();
dependencyMock.Verify(mock => mock.BulkInsert(expected), Times.Once());
}
}
Error message:
Expected invocation on the mock once, but was 0 times: mock => mock.BulkInsert([ThresholdCheck])
Performed invocations:
Mock<IThresholdCheckHandler:1> (mock):
IThresholdCheckHandler.GetQueuedChecks()
IThresholdCheckHandler.BulkInsert([ThresholdCheck])
If I change expected to It.IsAny<T>() in the Verify call, test passes. This leads me to believe that maybe somehow the objects passed from expected are somehow different from the objects generated when running the program. However as stated I've went through with the debugger and manually compared every value in the actual list to the expected list of values in the test and they are exactly the same.
This then leads me to believe that I'm just a stupid bipedal monkey clicking at a keyboard and that the problem is right in front of me and I'm just not seeing it. Any help or set of eyes is appreciated.
As per NKosi's comment, Verify operates via. reference when using reference types. I was confused as I'd used Verify in the past for simple things like ints and strings but was unaware of that quirk. One would assume with Verify that it would check the equivalency of actual vs. expected, but no.
Regardless then, as per Quercus's comment I adjusted my test to this in order to continue with my day:
public class ServiceTests
{
[Fact]
public void ServiceRun_Calls_DependencyBulkInsert()
{
var dependencyMock = new Mock<IDependencyService>();
List<T> actual = new List<T>();
List<T> expected = /* somehow build expected values */
dependencyMock
.Setup(mock => mock.BulkInsert(It.IsAny<IList<T>>()))
.Callback<List<T>>(l => actual = l);
var sut = new MyServiceClass(dependencyMock.Object);
sut.Run();
actual.Should().BeEquivalentTo(expected);
}
}
and this solution works for me. thanks to you both for helping me realize my mistake.
I am assigned to add unit test code coverage to a 15 years old legacy project which is not using IoC and 0 unit test. I am not allowed to refactor the code since it works perfect fine on production, management does not want other teams get involved for refactoring such as QA testing, etc.
Service class has a performService method has following code
public void performService(requestMessage, responseMessage) {
UserAccount userAccount = requestMessage.getUserAccount();
GroupAccount groupAccount = requestMessage.getGroupAccount();
Type type = requestMessage.getType();
StaticServiceCall.enroll(userAccount, groupAccount, type);
response.setStatus(Status.SUCCESS);
}
This StaticServiceCall.enroll method is calling remote service. My unit test is
#RunWith(PowerMockRunner.class)
#PrepareForTest(StaticServiceCall.class)
public class EnrollmentServiceTest {
#Test
public void testPerformService() {
mockStatic(StaticServiceCall.class);
doNothing().when(StaticServiceCall.enroll(any(UserAccount.class), any(GroupAccount.class), any(Type.class)));
service.performService(requestMessage, responseMessage);
assertEquals("Enrollment should be success, but not", Status.SUCCESS, response.getStatus);
}
Eclipse complains with The method when(T) in the type Stubber is not applicable for the arguments (void)
Eclipse stops complain if test code change to
mockStatic(StaticServiceCall.class);
doNothing().when(StaticServiceCall.class);
StaticServiceCall.enroll(any(UserAccount.class), any(GroupAccount.class), any(Type.class));
service.performService(requestMessage, responseMessage);
assertEquals("Enrollment should be success, but not", Status.SUCCESS, response.getStatus);
Test case failed with UnfinishedStubbingException. I am using powermock 1.6.6
There is a misconception on your end. You think that you need to say that doNothing() should do nothing.
That is not necessary! As these lines
#PrepareForTest(StaticServiceCall.class) ... and
mockStatic(StaticServiceCall.class);
are sufficient already.
You want to prevent the "real" content of that static method to run when the method is invoked during your test. And that is what mockStatic() is doing.
In other words: as soon as you use mockStatic() the complete implementation of the real class is wiped. You only need to use when/then/doReturn/doThrow in case you want to happen something else than nothing.
Meaning: just remove that whole doNothing() line!
#GhostCat - Thank you for your answer, it solved problem, my misconception is coming from this test case
#Test
public void testEnrollmentServiceSuccess() {
RequestMessage requestMessage = new RequestMessage();
requestMessage.setName("ENROLL");
ResponseMessage responseMessage = new ResponseMessage();
EnrollmentService mockService = mock(EnrollmentService.class);
mockService.performService(any(RequestMessage.class), any(ResponseMessage.class));
mockStatic(ClientManager.class);
when(ClientManager.isAuthenticated()).thenReturn(true);
ServiceImpl service = new ServiceImpl();
service.performService(requestMessage, responseMessage);
verify(mockService).performService(any(RequestMessage.class), any(ResponseMessage.class));
}
Here is the code snippet of ServiceImpl class based name of the request message calling different service class
public void performService(RequestMessage request, ResponseMessage response) {
try {
if (request == null) {
throw new InvalidRequestFormatException("null message");
}
if (!ClientManager.isAuthenticated()) {
throw new ServiceFailureException("not authenticated");
}
// main switch for known services
if ("ENROLL".equals(request.getName())) {
service = new EnrollmentService();
service.performService(request, response);
} else if ("VALIDATE".equals(request.getName())) {
...
Although the test passed,real implementation in EnrollmentService got called and exceptions thrown due to barebone RequestMessage object, then I googled out doNothing, thanks again for your clarification
Having some issues wrapping my head around class instantiation and TestDriven.Net(v4.0.3478) or XUnit(v2.2.0), RhinoMocks(v3.6.1), and structuremap.automocking(v4.0.0.315).
Given this code:
public class Tests1
{
[Fact]
public void passing_test()
{
var mocker = new RhinoAutoMocker<Subject>();
mocker.Get<IData>().Stub(x => x.Strings).Return(new List<string> {""});
var result = mocker.ClassUnderTest.GetStrings();
result.Count().ShouldEqual(1);
}
}
public class Tests2
{
[Fact]
public void passing_test()
{
var mocker = new RhinoAutoMocker<Subject>();
mocker.Get<IData>().Stub(x => x.Strings).Return(new List<string> {""});
var result = mocker.ClassUnderTest.GetStrings();
result.Count().ShouldEqual(1);
}
}
public class Subject
{
private readonly IData _data;
public Subject(IData data)
{
_data = data;
}
public IEnumerable<string> GetStrings()
{
return _data.Strings;
}
}
public interface IData
{
IEnumerable<string> Strings { get; set; }
}
All tests run fine when I right click -> Run Test(s) on specific test method or a specific class definition.
Tests fail when I right click on project, folder containing tests or the namespace definition of the class above.
The errors are NullReferenceException, when doing asserts, it seems to be the stub's data. It's random, sometimes Tests1.passing_test fails, sometimes Tests2.passing_test fails. Never both.
Thinking it has to with RhinoAutoMocker and/or the MockRepository not being reset between test fixtures?
UPDATE: simplified the code to show the problem, also given code is complete, using NUnit [Test] instead of XUnit [Fact] attributes works, everything behaves as normal.
In your example, you have two separate test classes.
By default, xUnit v2 will run these tests in parallel.
I have experienced the same issue, but in my case using the static MockRepository.GenerateMock.
The static class being used across the parallel tests results in exceptions.
The seeming randomness of the test failures depends on which tests run first.
There are two alternatives I can see.
1. Tests in a single class - not really workable
2. Use the XUnit Collection attribute to place all tests classes in the same collection - this worked for me.
see: http://xunit.github.io/docs/running-tests-in-parallel.html
Another alternative is to turn off parallelism for xUnit using the following attribute in your test assembly
[assembly: CollectionBehavior(DisableTestParallelization = true)]
I've got the following code and I need help to write a unit test for it. I'm using Moq library.
Here's the deal. I have a business class with a dependency to a repository (interface), so I can use it to save my entities to the database. My entity is basically a list of strings. The method AddAndSave, from MyBusinessClass, grab the value it receives as a parameters, put it into the list and call Save method from IRepository. Then, I clear the list of my entity. The code below show this example (I've made it simple so I can explain it here).
There's a unit test, too.
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace TestesGerais
{
public class MyEntity
{
public MyEntity()
{
MyList = new List<string>();
}
public List<string> MyList { get; set; }
}
public interface IRepository
{
void Save(MyEntity entity);
}
public class MyBusinessClass
{
public IRepository Repository { get; set; }
private MyEntity _entity = new MyEntity();
public void AddAndSave(string info)
{
_entity.MyList.Add(info);
Repository.Save(_entity);
_entity.MyList.Clear(); // for some reason I need to clear it
}
}
[TestClass]
public class UnitTest10
{
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<IRepository>();
MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object };
b.AddAndSave("xpto");
mock.Verify(m => m.Save(It.Is<MyEntity>(x => x.MyList[0] == "xpto")), Times.Exactly(1));
}
}
}
My unit-test check if the IRepository's Save method was called with its parameter (an entity) having one element in the list, and having the value "xpto" in this element.
When I run this test, it turns red with the error message "Test method TestesGerais.UnitTest10.TestMethod1 threw exception:
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index".
Ok, this is caused by the list that has been cleaned. If I comment the line "_entity.MyList.Clear();", everything goes well.
My question is: how can I test this without commenting the "Clear" line in my business class, and making sure that my repository's method is called passing the specific value (entity with one element with value "xpto")?
Thanks
I've changed my unit test using the Callback feature of Moq. This way, I can setup the mock so when AddAndSave is called, the parameter it receives is saved into a variable from my unit test, and I can assert it later.
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<IRepository>();
string result = string.Empty;
mock.Setup(m => m.Save(It.IsAny<MyEntity>())).Callback((MyEntity e) => { result = e.MyList[0]; });
MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object };
b.AddAndSave("xpto");
Assert.AreEqual(result, "xpto");
}
You could split your method up a bit. "AddAndSave" isn't all it does. You could then just test the behaviour of the adding and saving bit in isolation.
I've isolated the behaviour into the following test case. I'd be grateful to anyone who can tell me how to expect/verify a property set for a List<T> property - it appears there's something going on inside It.Is<T>(predicate) that isn't making a whole lot of sense to me right now. Sample code will run as a console app from VS2008 - you'll need to add a reference to Moq 2.6 (I'm on 2.6.1014.1) - please try uncommenting the different ExpectSet statements to see what's happening...
using System;
using Moq;
using System.Collections.Generic;
namespace MoqDemo {
public interface IView {
List<string> Names { get; set; }
}
public class Controller {
private IView view;
public Controller(IView view) {
this.view = view;
}
public void PopulateView() {
List<string> names = new List<string>() { "Hugh", "Pugh", "Barney McGrew" };
view.Names = names;
}
public class MyApp {
public static void Main() {
Mock<IView> mockView = new Mock<IView>();
// This works - and the expectation is verifiable.
mockView.ExpectSet(mv => mv.Names);
// None of the following can be verified.
// mockView.ExpectSet(mv => mv.Names, It.Is<Object>(o => o != null));
// mockView.ExpectSet(mv => mv.Names, It.Is<List<string>>(names => names.Count == 3));
// mockView.ExpectSet(mv => mv.Names, It.IsAny<IList<String>>());
Controller controller = new Controller(mockView.Object);
controller.PopulateView();
try {
mockView.VerifyAll();
Console.WriteLine("Verified OK!");
} catch (MockException ex) {
Console.WriteLine("Verification failed!");
Console.WriteLine(ex.Message);
}
Console.ReadKey(false);
}
}
}
}
I'm not using the very latest version of Moq, so I don't have an overload of ExpectSet that takes two parameters, but I've had some success with this pattern:
mockView.ExpectSet(mv => mv.Names).Callback(n => Assert.That(n != null));
The Assert (from NUnit) call in the callback will throw an exception if the value assigned to .Names doesn't match the predicate. It does make it hard to trace when a test fails, though. I agree that the ability to pass an It.Is or It.IsAny as the second parameter would be handy.
The second parameter of ExpectSet() is the value you're expecting. You can't use It.Is<T> in this case as there's no overload that takes a predicate - though it would be nice ;) Here's a (simplified) excerpt from your sample, illustrating the use of a value:
var mockView = new Mock<IView>();
var list = new List<string> { "Hugh", "Pugh", "Barney McGrew" };
mockView.ExpectSet(mv => mv.Names, list);
mockView.Object.Names = list;
Hope that helps.
Edit: fixed typo.
BTW, It.Is is not supported on ExpectSet. Your code compiles just because they are regular method invocations when used as values (as opposed to expressions), whereas when used in an Expect expression they are pre-processed by Moq and given specific meaning (rather than the null/default value that all It.Is members actually return).
You could use the stub behavior on the given property (mockView.Stub(mv => mv.Names)) and later assert directly for its value after execution.
Moq doesn't provide an overload receiving It.IsAny as it's effectively the same as calling ExpectSet without passing an expected value ;)