Unit test, Rhino, The art of unit testing - unit-testing

I've started to read "The art of unit testing" and I'm trying to implement this piece of code:
[Test]
public void ReturnResultsFromMock()
{
MockRepository mocks = new MockRepository();
IGetResults resultGetter = mocks.DynamicMock<IGetResults>();
using(mocks.Record())
{
resultGetter.GetSomeNumber("a");//#1
LastCall.Return(1);
resultGetter.GetSomeNumber("a");//#2 how it should work?
LastCall.Return(2);
resultGetter.GetSomeNumber("b");
LastCall.Return(3);
}
int result = resultGetter.GetSomeNumber("b");
Assert.AreEqual(3, result);
int result2 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(1, result2);
int result3 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(2, result3);
}
I get this error message after running my test
AOUT.Loga.Tests.LogAnalyzerTest.ReturnResultsFromMock:
Expected: 2
But was: 1

Looks like you try to implement ordered sequence of calls (see details here):
First you call GetSomeNumber("a") should returns 1
Then call GetSomeNumber("a") again, result will be 2
And only then GetSomeNumber("b"), result will be 3
Is so, try to replace using(mocks.Record()) with using(mocks.Ordered()). But, this will work only in this sequence of calls
At your example, you are using using(mocks.Record()), so every call to GetSomeNumber("a") will return 2 acording to your configuration. You're override first GetSomeNumber("a") by second one. Here are correct assumptions:
int result = resultGetter.GetSomeNumber("b");
Assert.AreEqual(3, result);
int result2 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(2, result2); // every call to GetSomeNumber("a") will returns 2
int result3 = resultGetter.GetSomeNumber("a");
Assert.AreEqual(2, result3);

You may try using the simpler Rhino Mocks AAA syntax, your code will look something like this (take a look also at this question):
// Arrange
var resultGetter = MockRepository.GenerateMock<IGetResults>;
resultGetter.Expect(x => x.GetSomeNumber("b")).Return(3);
resultGetter.Expect(x => x.GetSomeNumber("a")).Return(1).Repeat.Once();
resultGetter.Expect(x => x.GetSomeNumber("b")).Return(2).Repeat.Once();
// Act
int result = resultGetter.GetSomeNumber("b");
// Assert
Assert.AreEqual(3, result);
// Act
int result2 = resultGetter.GetSomeNumber("a");
// Assert
Assert.AreEqual(1, result2);
// Act
int result3 = resultGetter.GetSomeNumber("a");
// Assert
Assert.AreEqual(2, result3);

Related

How to use Moq to Verify that PropertyChanged is invoked with the expected object and property name?

Using NUnit and Moq, I'd like to replace the PropertyChanged handler code in the following test by Moq if it makes the test shorter and clearer. I'm currently unclear as to how to do this in Moq, verifying that PropertyChanged is invoked once for IsDirty and once for LocalDatabaseFilePath, each time with the expected object (o in the code). Can anybody advise how to do this with Moq please?
[Test]
[Category("Fast Tests")]
[Category("PropertyChanged Events")]
public void FactoryResetCommand_AllPropertiesChangedInViewModel_PropertyChangedEventsFiredAsExpected()
{
// Arrange
string expectedLocalDatabaseFilePath = "eldfp";
string otherLocalDatabaseFilePath = "other" + expectedLocalDatabaseFilePath;
Mock<IDataStoreSettingsDataModel> stubDataModel = new Mock<IDataStoreSettingsDataModel>();
stubDataModel.Setup(x => x.LocalDatabaseFilePath).Returns(expectedLocalDatabaseFilePath);
IDataStoreSettingsViewModel sutViewModel = new DataStoreSettingsViewModel(
stubDataModel.Object,
ReportExceptionAsync);
sutViewModel.LocalDatabaseFilePath = otherLocalDatabaseFilePath;
sutViewModel.IsDirty = false;
// I'd like to replace the following by Moq if shorter/clearer
int propertyChangedCountIsDirty = 0;
int propertyChangedCountLocalDatabaseFilePath = 0;
object? objIsDirty = null;
object? objLocalDatabaseFilePath = null;
sutViewModel.PropertyChanged += ((o, e) =>
{
switch (e?.PropertyName)
{
case nameof(DataStoreSettingsViewModel.IsDirty):
objIsDirty = o;
++propertyChangedCountIsDirty;
break;
case nameof(DataStoreSettingsViewModel.LocalDatabaseFilePath):
objLocalDatabaseFilePath = o;
++propertyChangedCountLocalDatabaseFilePath;
break;
}
});
// I'd like to replace the above by Moq if shorter/clearer
// Act
if (sutViewModel.FactoryResetCommand.CanExecute(null))
sutViewModel.FactoryResetCommand.Execute(null);
// Assert
Assert.AreEqual(1, propertyChangedCountIsDirty);
Assert.AreEqual(1, propertyChangedCountLocalDatabaseFilePath);
Assert.AreSame(sutViewModel, objIsDirty);
Assert.AreSame(sutViewModel, objLocalDatabaseFilePath);
}
Worked it out myself.
After adding the following interface:
public interface IPropertyChangedEventHandler
{
void PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e);
}
The test using Moq looks like this:
[Test]
[Category("Fast Tests")]
[Category("PropertyChanged Events")]
public void FactoryResetCommand_AllPropertiesChangedInViewModel_PropertyChangedEventsFiredAsExpected()
{
// Arrange
string originalLocalDatabaseFilePath = "oldfp";
string otherLocalDatabaseFilePath = "other" + originalLocalDatabaseFilePath;
Mock<IPropertyChangedEventHandler> mockPropertyChangedEventHandler = new Mock<IPropertyChangedEventHandler>();
Mock<IDataStoreSettingsDataModel> stubDataModel = new Mock<IDataStoreSettingsDataModel>();
stubDataModel.Setup(x => x.LocalDatabaseFilePath).Returns(originalLocalDatabaseFilePath);
IDataStoreSettingsViewModel sutViewModel = new DataStoreSettingsViewModel(
stubDataModel.Object,
ReportExceptionAsync);
sutViewModel.LocalDatabaseFilePath = otherLocalDatabaseFilePath;
sutViewModel.IsDirty = false;
sutViewModel.PropertyChanged += mockPropertyChangedEventHandler.Object.PropertyChanged;
// Act
if (sutViewModel.FactoryResetCommand.CanExecute(null))
sutViewModel.FactoryResetCommand.Execute(null);
// Assert
mockPropertyChangedEventHandler.Verify(x => x.PropertyChanged(sutViewModel,
It.Is<System.ComponentModel.PropertyChangedEventArgs>(e => e.PropertyName == nameof(DataStoreSettingsViewModel.IsDirty))),
Times.Once);
mockPropertyChangedEventHandler.Verify(x => x.PropertyChanged(sutViewModel,
It.Is<System.ComponentModel.PropertyChangedEventArgs>(e => e.PropertyName == nameof(DataStoreSettingsViewModel.LocalDatabaseFilePath))),
Times.Once);
}

Are Jest timer mocks broken in Stencil 1.0.2?

I'm using StencilJS v1.0.2 and it runs unit tests in Jest. I have the following code but it doesn't seem to behave as expected. Am I using the API correctly?
function ok( delay: number ) {
setTimeout(() => {
return 3;
}, delay);
}
test( 'timer', () => {
jest.useFakeTimers();
const result = ok( 1000 );
jest.advanceTimersByTime( 999 );
expect( result ).toBeUndefined();
jest.runAllTimers();
expect( result ).toBe( 3 );
} );
the test should pass but instead it fails on the last expect statement
This line:
const result = ok( 1000 );
...sets result to the return value of ok...
...but ok doesn't return anything so result is always undefined.
So the first expect passes:
expect( result ).toBeUndefined(); // Success!
...but the second expect fails since result will always be undefined:
expect( result ).toBe( 3 ); // <= FAILS since result is always undefined
The issue is that setTimeout just calls the function passed to it.
If the function returns a value then it just gets lost so this line:
return 3;
...doesn't actually do anything.
A simple way to fix the test is to have ok return an object...
...and have the function passed to setTimeout set a property on the object like this:
function ok(delay: number) {
const result: { val?: number } = {};
setTimeout(() => {
result.val = 3; // <= set a property on result
}, delay);
return result;
}
test('timer', () => {
jest.useFakeTimers();
const result = ok(1000);
jest.advanceTimersByTime(999);
expect(result.val).toBeUndefined(); // Success!
jest.runAllTimers();
expect(result.val).toBe(3); // Success!
});

Error "Expected invocation on the mock once, but was 0 times" when unit testing with moq

I have the following class I want to test:
public interface ISqlServiceByModule
{
DataSet GetPagedAggregateData(int clientId, int moduleId, int billTypeId, PagedTable result);
}
public class IncidentModuleService : IIncidentModuleService
{
private readonly ISqlServiceByModule sqlServiceByModule;
public IncidentModuleService(ISqlServiceByModule sqlServiceByModule)
{
if (sqlServiceByModule == null) throw new ArgumentNullException("sqlServiceByModule");
// Inject the ISqlServiceByModule dependency into the constructor
this.sqlServiceByModule = sqlServiceByModule;
}
public PagedTable GetData(int clientId, int moduleId, int billTypeId, Dictionary<string, string> queryStringParameters)
{
PagedTable result = new PagedTable(queryStringParameters);
DataSet dataSet = this.sqlServiceByModule.GetPagedAggregateData(clientId, moduleId, billTypeId, result);
// Map the DatSet to a PagedTable
if (dataSet == null || dataSet.Tables.Count == 0)
{
result.SetPagesFromTotalItems(0);
}
else
{
result.SetPagesFromTotalItems(Convert.ToInt16(dataSet.Tables[1].Rows[0][0]));
result.Listings = dataSet.Tables[0];
}
return result;
}
}
Specifically, I want to test the GetData method. My unit test looks like this:
[TestClass]
public class IncidentModuleServiceUnitTest
{
private DataSet incidentsData;
[TestInitialize]
public void SetUp()
{
this.incidentsData = new DataSet();
}
[TestMethod]
public void GetDataTestGetPagedAggregateDataIsCalled()
{
//-- Arrange
int billTypeId = 1;
int clientId = 1;
int moduleId = 1;
Dictionary<string, string> queryStringParameters = new Dictionary<string,string>();
PagedTable tempResult = new PagedTable(queryStringParameters);
DataSet dataSet = new DataSet();
dataSet.Tables.Add(new DataTable());
var mockSqlService = new Mock<ISqlServiceByModule>();
mockSqlService.Setup(r => r.GetPagedAggregateData(clientId, moduleId, billTypeId, tempResult)).Returns(this.incidentsData);
IncidentModuleService target = new IncidentModuleService(mockSqlService.Object);
//-- Act
var actual = target.GetData(clientId, moduleId, billTypeId, queryStringParameters);
//-- Assert
Assert.IsNull(actual.Listings);
mockSqlService.Verify(r => r.GetPagedAggregateData(clientId, moduleId, billTypeId, tempResult), Times.Once);
}
}
The error I am getting happens on the last line:
mockSqlService.Verify(r => r.GetPagedAggregateData(clientId, moduleId, billTypeId, tempResult), Times.Once);
And the exact error message is this:
{"\r\nExpected invocation on the mock once, but was 0 times: r =>
r.GetPagedAggregateData(.clientId, .moduleId, .billTypeId, .tempResult
Configured setups:\r\nr => r.GetPagedAggregateData(.clientId,
.moduleId, .billTypeId, .tempResult),
Times.Never
Performed invocations:\r\nISqlServiceByModule.GetPagedAggregateData(1,
1, 1, PagedTable)"}
Any idea why this is happening? It looks to me like the method in question is being called, but Moq doesn't like the parameters for some reason, even though they are the exact same ones in all three invocations, as far as I can tell.
PagedTable is a reference type not a value type. Therefore the parameters in Setup don't match what was called even though they look like they should be the same. You could use It.IsAny<PagedTable>() instead of tempResult.
See this answer for an example of how to check that the PagedTable parameter was the correct one.

Qt cpp code..how object.function1.function2 works

I am unable to get how this will work...
how object.function1.function2 works
following is the code
l_floatValue = l_objMeter.getWATTHrs().getChannelA();
function 1 retrun you object and you call method of it
Please consider following example
int len = QString(" TEST ").simplified().length();
Suppose
QString test = QString(" TEST "); // will create string object of lengh 6
QString simTest = test.simplified(); // Will create string of len 4 remove white spaces
int len = simTest.length(); // len 4
This is how program will work

How to use Given/When/Then pattern with mocks (Google Mock)?

I'm using the Given/When/Then pattern to make test code much clearer. Since I'm writing those tests in C++ I chosed to use Google Test. With tests the pattern is clear, because I do sth like this:
TEST(TestFixture, TestName)
{
// Given
int a = 5;
int b = 6;
int expectedResult = 30;
// When
int result = Multiply(a, b);
// Then
EXPECT_EQ(expectedResult, result);
}
But with mocks it stops being clear since there appear some EXPECTs in the Given part. The Given part suppose to be a setup step. Please see an example:
TEST(TestFixture, TestName)
{
// Given
int a = 5;
int b = 6;
int expectedResult = 30;
MightCalculatorMock mock;
EXPECT_CALL(mock, multiply(a,b))
.WillOnce(Return(expectedResult));
// When
int result = Multiply(mock, a, b);
// Then
EXPECT_EQ(expectedResult, result);
}
Is this approach correct? How the Given/When/Then comments should be placed in the test code, where?
The EXPECT_CALL macro can be thought of as a way of testing interaction between a class and another class. As such, if you are using it with another EXPECT macro, then your test is likely testing two things, which is why it appears to conflict with the "Given-When-Then" paradigm (also known as "Arrange-Act-Assert").
If you just need to set up some behavior on your mock object for testing, use the ON_CALL macro instead:
TEST(TestFixture, TestName)
{
// Given
int a = 5;
int b = 6;
int expectedResult = 30;
MightCalculatorMock mock;
ON_CALL(mock, multiply(a,b))
.WillByDefault(Return(expectedResult));
// When
int result = Multiply(mock, a, b);
// Then
EXPECT_EQ(expectedResult, result);
}
If you are actually looking to test the iteraction between your system under test and some other collaborator, you can use an "Arrange-Expect-Act" pattern:
TEST(TestFixture, CalculatorIsCalledProperly)
{
// Arrange
int a = 5;
int b = 6;
int expectedResult = 30;
MightCalculatorMock mock;
// Expect
EXPECT_CALL(mock, multiply(Eq(a),Eq(b)));
// Act
int result = Multiply(mock, a, b);
}