Code Contracts throws MethodAccess Exception when unit testing - unit-testing

I'm not quite sure why, but when I enable runtime contract checking, I'm getting a MethodAccessException during unit testing. I use the Machine.Specifications test framework and the ReSharper/dotCover test runner. When I test my assembly containing code contracts, I get this MethodAccessException:
Machine.Specifications.SpecificationException Should be of type System.ArgumentNullException but is of type System.MethodAccessException
at BusinessLogic.Specifications.When_testing_whether_a_set_of_cart_items_contains_a_product_and_a_null_set_is_passed.<.ctor>b__3()
in CartItemQuerySpecs.cs: line 66
The specification looks like this:
[Subject(typeof(ShoppingCartQueries), "Cart contains product")]
public class When_testing_whether_a_set_of_cart_items_contains_a_product_and_a_null_set_is_passed
: with_fake_shopping_cart_repository
{
Establish context = () => QueryResult = CartItems.AsQueryable().ForUser(UserWithNoProductsInCart);
Because of = () => Thrown = Catch.Exception(() => result = QueryResult.ContainsProduct(100));
It should_throw = () => Thrown.ShouldBeOfType<ArgumentNullException>();
static bool result;
}
The unit under test looks like this:
[Pure]
public static bool ContainsProduct(this IQueryable<CartItem> items, int id)
{
Contract.Requires<ArgumentNullException>(items != null);
return (items.Any(item => item.ProductId.Equals(id)));
}
Why would I get a MethodAccessException?

Related

How to unit test a transaction-wrapped function in Prisma?

I'm very new to Prisma and NestJS. I have the following transaction-wrapped function that I want to unit test by mocking the internal function reserveSingleBook.
This is my code (it does a few actions in a for loop and I want all those actions to be successful before committing the transaction).
async reserveBooks(reserveBooksDto: ReserveBoksDto): Promise<SuccessfulReservationResponse> {
return await this.prisma.$transaction(async (prisma) => {
const reservedBooksResponse = new SuccessfulReservationResponse();
for (const reservation of reserveBooksDto.reservations){
const bookBucket = await this.reserveSingleBook(
prisma,
reserveBooksDto.libraryId,
reservation,
);
const successfulReservation = new SuccessfulReservation();
successfulReservation.book_bucket_id = bookBucket.id;
successfulReservation.units_reserved = reservation.units;
reservedBookssResponse.successful_reservations.push(successfulReservation);
}
return reservedBooksResponse
})
}
This is how I'm currently unit testing it:
it('should throw an exception when at least a parent book does not exist', async () => {
// Arrange
const nonExistingParentBookId = 'non-existing-parentbook-id';
const existingParentBookId = 'existing-parent-book-id';
const mock = jest.spyOn(service, 'reserveSingleBook');
mock
.mockResolvedValueOnce(
{
parentBookId: existingParentBookId,
reserved: 10,
used: 0,
} as BookBucket
)
.mockRejectedValueOnce(new NotFoundException())
const reserveBooksDto = new ReserveBooksDto();
reserveBooksDto.library_id= 'abcde';
const firstReservation = new Reservation();
firstReservation.book_id= nonExistingParentBookId;
firstReservation.units = 10;
const secondReservation = new Reservation();
secondReservation.book_id= existingParentBookId;
secondReservation.units = 10;
reserveBooksDto.reservations = [firstReservation, secondReservation];
// Act / Assert
await expect(service.reserveBooks(
reserveBooksDto
)).rejects.toThrowError(NotFoundException);
expect(mock).toBeCalledTimes(2);
mock.mockRestore();
});
The unit test works PERFECTLY if I remove the transaction, since my second mock call returns the NotFoundException, which is then passed on to ReserveBooks.
However, when I have the transaction in place (don't want anything commited if anything fails), I get an 'undefined' resolved in my function call, instead of the exception thrown.
Does anybody know what I might be doing wrong?
Thanks in advance!!

IllegalArgumentException while running contract unit test in Kotlin (Corda)

When I try to run my Junit tests (Wrote in Kotlin) I get the following exception :
java.lang.IllegalArgumentException: Attempted to find dependent attachment for class javax/xml/bind/DatatypeConverter, but could not find a suitable candidate.
I tried to comment/decomment some lines in following code, it seems that the exception occurs when I call command()
class IRIssueTests {
class DummyCommand : TypeOnlyCommandData()
private val ledgerServices = MockServices(listOf("com.my.package.name"))
private val ALICE = TestIdentity(CordaX500Name(organisation = "Alice", locality = "TestLand", country = "US"))
#Test
fun mustIncludeIssueCommand() {
val ir = IRState(
UniqueIdentifier(),
mutableListOf(ALICE.party)
)
ledgerServices.ledger {
transaction {
output(IRContract.ID, ir)
command(listOf(ALICE.publicKey), DummyCommand())
fails()
}
transaction {
output(IRContract.ID, ir)
command(listOf(ALICE.publicKey), IRContract.Commands.Issue())
verifies()
}
}
}
}
I would like to understand why I'm getting this exception and how to resolve it to make my test passing
Kotlin tests must be run with JDK8.
Change configuration of JDK8 in your project before running tests.
This will avoid this exception

Using Spock to test Spring JdbcTemplate

I have the following Java 8 DAO method that uses Spring JdbcTemplate to hit a database:
class MyAppDao {
#Inject
DataSource dataSource
public List<String> getFizzByBuzzIds(List<Integer> buzzIds) {
String sql = "SELECT * from buzzes WHERE buzz_id IN ( :buzzIds )";
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
Map<String, Object> paramValues = new HashMap<>(1);
paramValues.put("buzzIds", buzzIds);
List<Buzz> buzzes = jdbcTemplate.query(sql,
paramValues, (rs, rowNum) -> {
return new Buzz(rs.getString("buzz_id"), rs.getString("buzz_key"),
rs.getString("buzz_external_id"));
}
);
List<String> fizzes = figureOutSomehow();
return fizzes;
}
}
I cannot change the dependencies injected into this method. The NamedParameterJdbcTemplate instance must be defined inside this method. The only thing I can mock (easily) is the dataSource.
I am trying (and I know, the method isn't written to be conducive to unit tests at all!) to write a Spock unit test for this, and just want to verify that when getFizzByBuzzIds is called, that jdbcTemplate.query is called (with any arguments).
My best attempt:
def 'getFizzByBuzzIds attempts to get case info from the DB'() {
given:
MyAppDao dao = Spy(MyAppDao, constructorArgs: [ dataSource ]) {
getJdbcTemplate() >> Mock(JdbcTemplate) {
1 * query('', null) // ???
}
}
when:
List<Integer> buzzIds = [1, 2, 3, 4]
dao.getFizzByBuzzIds(buzzIds)
then:
1 * dao.jdbcTemplate.query('', null) // ???
}
How can I configure the Spy and the then block label so that executing getFizzByBuzzIds verifies whether the underlying JdbcTemplate.query(...) method is called?

When using Moq Verify() method invocation count, have failing test's error message contain actual method invocation count using Moq

Consider the following, where I am testing that an injected dependency's method is called a specific number of times:
[Fact]
public void WhenBossTalksEmployeeBlinksTwice()
{
// arrange
var employee = new Mock<IEmployee>();
employee.Setup(e => e.Blink());
var boss = new Boss(employee.Object);
// act
boss.Talk();
// assert
employee.Verify(e => e.Blink(), Times.Exactly(2)); // Passes as expected
employee.Verify(e => e.Blink(), Times.Exactly(1)); // Fails as expected
}
When I force the failing test, the output is:
Moq.MockException: Invocation was not performed on the mock 1 times: e
=> e.Blink()
What would be better is something like:
Moq.MockException: Invocation was unexpectedly performed 2 times, not 1 time: e
=> e.Blink()
Here are the items involved with the test:
public interface IEmployee { void Blink(); }
public class Boss {
private readonly IEmployee _employee;
public Boss(IEmployee employee) { _employee = employee; }
public void Talk() {
_employee.Blink();
_employee.Blink();
}
}
Is it possible to harvest and display the actual number of times the dependency's method was called, in the failing test's error message?
I'm not sure that it matters, but I'm using Moq v3.1.416.3 (not the latest, I know, but another library I'm using hasn't updated to Moq 4.x yet…)
I don't know of a straight way to harvest the information in Moq3.
What I would do is use a callback on the setup of Blink.
int count = 0;
employee.Setup(e => e.Blink()).Callback(() => count++);
...
employee.Verify(e => e.Blink(), Times.Exactly(1), "Moq.MockException: Invocation was unexpectedly performed " + count + " times, not 1 time: e => e.Blink()"); // Fails as expected

Using Moq to mock a repository that returns a value

How do I set up my test method on that mocks a repository which accepts an object?
This is what I have so far:
Service.cs
public int AddCountry(string countryName)
{
Country country = new Country();
country.CountryName = countryName;
return geographicsRepository.SaveCountry(country).CountryId;
}
test.cs
[Test]
public void Insert_Country()
{
//Setup
var geographicsRepository = new Mock<IGeographicRepository>();
geographicsRepository.Setup(x => x.SaveCountry(It.Is<Country>(c => c.CountryName == "Jamaica"))); //How do I return a 1 here?
GeographicService geoService = new GeographicService(geographicsRepository.Object);
int id = geoService.AddCountry("Jamaica");
Assert.AreEqual(1, id);
}
SaveCountry(Country country); returns an int.
I need to do 2 things:
First test, I need to tell the setup to return an int of 1.
I need to create a second test Insert_Duplicate_Country_Throws_Exception(). In my Setup, how do I tell the repository to throw an error when I do:
int id = geoService.AddCountry("Jamaica");
int id = geoService.AddCountry("Jamaica");
Framework:
NUnit.
Moq.
ASP.NET MVC - repository pattern.
Your first test should look something like this:
[Test]
public void Insert_Country()
{
Mock<IGeographicRepository> geographicsRepository = new Mock<IGeographicRepository>();
GeographicService geoService = new GeographicService(geographicsRepository.Object);
// Setup Mock
geographicsRepository
.Setup(x => x.SaveCountry(It.IsAny<Country>()))
.Returns(1);
var id = geoService.AddCountry("Jamaica");
Assert.IsInstanceOf<Int32>(id);
Assert.AreEqual(1, id);
geographicsRepository.VerifyAll();
}
The second test should look like this:
[Test]
public void Insert_Duplicate_Country_Throws_Exception()
{
Mock<IGeographicRepository> geographicsRepository = new Mock<IGeographicRepository>();
GeographicService geoService = new GeographicService(geographicsRepository.Object);
// Setup Mock
geographicsRepository
.Setup(x => x.SaveCountry(It.IsAny<Country>()))
.Throws(new MyException());
try
{
var id = geoService.AddCountry("Jamaica");
Assert.Fail("Exception not thrown");
}
catch (MyException)
{
geographicsRepository.VerifyAll();
}
}
I think maybe you are slightly misunderstanding the purpose of testing with mocks in the two scenarios you have supplied.
In the first scenario, you wish to test that 1 is returned when you pass in "Jamaica". This is not a mock test case but a test case for real behaviour as you wish to test a specific input against an expected output i.e. "Jamaica" -> 1. In this situation mocking is more useful to ensure that internally your service calls SaveCountry on the repository with the expected country, and that it returns the value from the call.
Setting up your "SaveCountry" case and then calling "VerifyAll" on your mock is the key. This will assert that "SaveCountry" was indeed called with country "Jamaica", and that the expected value is returned. In this way you have confidence that your service is wired up to your repository as expected.
[Test]
public void adding_country_saves_country()
{
const int ExpectedCountryId = 666;
var mockRepository = new Mock<IGeographicRepository>();
mockRepository.
Setup(x => x.SaveCountry(It.Is<Country>(c => c.CountryName == "Jamaica"))).
Returns(ExpectedCountryId);
GeographicService service= new GeographicService(mockRepository.Object);
int id = service.AddCountry(new Country("Jamaica"));
mockRepo.VerifyAll();
Assert.AreEqual(ExpectedCountryId, id, "Expected country id.");
}
In the second scenario you wish to test that an exception is raised when you attempt to add a duplicate country. There's not much point in doing this with a mock as all you will test is that your mock has behaviour when adding duplicates, not your real implementation.