Magnus Mårtensson
Microsoft Regional Director, Azure MVP, CEO Loftysoft
Avirag Jain
Director & CTO R Systems
Mahesh Chand
Founder C# Corner, CEO Mindcracker
Chris Gali
CEO & Co-Founder Graphite
Subinder Khurana
Chief Architect StoryProcess, Founder NASSCOM DeepTech Club
Bryan Rishforth
Investor, Chairman Graphite
Bryn Everson
Director Biz Dev Graphite
Raj Tiwari
Digital Transformation Leader, Futurist and Visionary
Joseph Guadagno
Microsoft MVP, Lead Quicken Loans
Nikita Sachdev
Entrepreneur, Blockchain Enthusiast & Advisor, Social Media Influencer
Doug Wagner
COO & Founder Adapt Technical Group
Ritesh Modi
Architect, Senior Evangelist, Cloud Architect
Crystal Wenrick
Director Communications Mindcracker
Allen O’Neill
Microsoft MVP, Consulting Engineer/Architect
Praveen Kumar
CEO MCN Solutions
Chris Love
Founder Love2Dev, Microsoft MVP, Author
Sanjay Vyas
Microsoft Regional Director, Microsoft MVP, Founder & CEO SkillLabs Technologies
Veena Sarda
Deep Learning Consultant, Author
Sekhar Srinivasan
C# Corner MVP, Microsoft Certified Trainer, Pluralsight Author
Lalit Bansal
Founder & CEO - EIY SYS
Navdeep Garg
CEO Revinfotech
Prakash Tripathi
Tech Manager/Leader, Microsoft MVP, Blogger
Bhavna Jain
Breakthrough Consultant
Naveen Sharma
Enterprise Architect, Leadership Coach, Author
Vidya Vrat Agarwal
Principal Architect, Microsoft MVP, Author
Sheetal Agarwal
Founder Clownselors, Medical Clown, Trainer
Abhishek Kant
Founder GTM Catalyst
Vishnu Saran
Founder & CEO VoiceQube
Sandeep Soni
Founder & CEO Deccansoft, Microsoft Certified Trainer
Parveen Malik
AVP InfoSec & Vulnerability Management, Information Security Expert
Nitin Pandit
Microsoft MVP, Developer Evangelist, Author
Niloshima Srivastava
C# Corner MVP, Tech Architect, Trainer, Blogger
Bala Chirtsabesan
Senior Software Engineer at Microsoft, Author
Manoj Mittal
Sr. Technical Architect, C# Corner MVP, Author
Chandni Di
Co-Founder Voice of Slum
Vithal Wadje
Technical Lead, Microsoft MVP, Author
Shivam Ahuja
Founder SkillCircle, Business Mentor
Chervine Bhiwoo
Solution Architect, Microsoft MVP, Author
Saurabh Jain
Vice President Paytm, Founder Fun2Do Labs, Author
Vinay Solanki
Head IoT at Lenovo, Founder IoT-NCR
Anshu kumari
Founder Blockchainkids, Inventor, Trainer
Amit Singal
CEO Startup Buddy
Dev Pratap
Co-Founder & CEO Voice of Slum
Amey Vartak
Technology Consultant, Full Stack Developer, C# Corner MVP, Author
Viswanatha Swamy
Principal Software Engineer, C# Corner MVP, Author
Sanket Verma
Research Engineer @ Ballistics (Forensics) and Chair, PyData Delhi
Sourabh Somani
Lead Developer, Microsoft MVP, Author
Abhishek Mishra
Software Architect, C# Corner MVP, Author
Siddharth Vaghasia
Technical Consultant, C# Corner MVP, Blogger
Bassam Alugili
Senior Software Specialist, Database Expert
S Ravi Kumar
Solution Architect, C# Corner MVP, Author
Sundaram Subramanian
Full Stack Developer, C# Corner MVP, Speaker
Deepesh Somani
Solution Architect, Microsoft MVP, Author
Debasis Saha
Technical Project Manager, C# Corner MVP, Blogger, Author
Vipul Jain
Software Architect, C# Corner MVP, Author
Akshay Patel
Technical Architect, Microsoft Certified Trainer, C# Corner MVP, Author
Stephen Simon
RPA Developer, Evangelist, Author
Vivek Sharma
Founder Kingster636, AR/VR Specialist
Jeetendra Gund
Technical Lead, C# Corner MVP, Author
Sujal Beniwal
AI Enthusiast, Student
M Viknaraj
Microsoft MVP, Azure Architect, Author
Prasham Sabadra
Software Architect, C# Corner MVP, Trainer, Author
Aakash Maurya
Senior Developer, C# Corner MVP, Speaker
Ankit Sharma
Senior Software Engineer, C# Corner MVP, Author
Mangesh Gaherwar
Team Lead, C# Corner MVP, Author
Viral Jain
Technical Consultant, C# Corner MVP, Author
Bhasker Das
Solution Architect, Evangelist
Manish Dwivedi
Associate Project Manager
Ck Nitin
Programmer, Author
Rohit Gupta
Technical Trainer, Author
Manish Tewatia
Full-stack Marketer, UX Designer
Bhavya Gaur
Technical Illustrator
Rohit Tomar
SEO/SMO Expert
Web Track
Cloud & Data Track
Dev Track
Registration & Breakfast
Future of Desktop Apps with JS (ElectronJs)
Nitin Pandit
Building Serverless Microservices Using Microsoft Azure
Vithal Wadje
Innovating RPA: A Robot for Every Person
Stephen Simon
Managing Cloud Storage Accounts using Logic Apps
Viknaraj Manogararajah
Data visualization using Python
Sekhar Srinivasan
Going Cross platform with AR Foundation
Vivek Sharma
Keynote
Managing your Azure dependencies in ASP.NET Core apps using VS
Bala Chirtsabesan
Securing Applications on Intelligent Azure
Abhishek Mishra
Getting started with Blazor the Framework of Future
S Ravi Kumar
Lunch
Build Progressive Web Apps using Angular 9
Debasis Saha
Build and deploy to any platform using Azure DevOps
Chervine Bhiwoo
Deep Dive in Azure Service Bus
Akshay Patel
Build a Native Mobile Application using React Native and JavaScript
Joseph Guadagno
Making sense of Web Job, Web Job SDK and Functions in Azure
Prakash Tripathi
CloudFront Distribution in AWS
Viral Jain
Tea Break
Introduction to PowerBI
Aakash Maurya
Build Advanced SPFx solutions with React and Graph API
Siddharth Vaghasia
Build Business Intelligence Analyst (BIA) Skills
Sundaram Subramanian
Deep dive of Power Platform – AI BUILDER
Prasham Sabadra
Panel 1
What's new in SharePoint development
Vipul Jain
Build a SSO (Single Sign On) based Native JavaScript application with Microsoft Identity within 10 minutes
Manoj Mittal
Panel 2
Applications and working of AI
Veena Sarda
Deploying serverless API's with .Net core 3.0 on AWS & Azure
Amey Vartak
Panel 3
Blockchain with .NET Core (Ark)
Anshu Kumari
Closing Note & Prize Distribution
Dev Track
Cloud Track
Architecture Track
Emerging Tech Track
Registration & Breakfast
Creating Full-Stack Web Apps Using Server-Side Blazor
Ankit Sharma
Real time face recognition with MS Cognitive Services
Niloshima Srivastava
Building Scalable APIs with GraphQL
Jeetendra Gund
Future of development with AI and Blockchain
Navdeep Garg
Debugging Tips and Tricks with Visual Studio 2019
Joseph Guadagno
Azure Containers
Abhishek Kant
Enterprise Architecture
Naveen Sharma
Bot Framework - learn it fast and look like a boss!
Allen O’Neill
Keynote
.Net Core & C# 8 Performance
David McCarter
Working with Azure kubernetes services
Ritesh Modi
Becoming an Architect
Vidyavrat Agarwal
Why Techies Need to Learn Product Management
Saurabh Jain
Lunch
Build a rules engine in .Net Core
Sanjay Vyas
Building CI and CD Pipeline using Azure DevOps
Sandeep Soni
Entity Framework Core - Tips and Tricks, Performance Optimization, and Tuning
Bassam Alugili
Hacking your way into Data Science
Sanket Verma
Speed up your .Net Core Website
Sourabh Somani
Azure
Magnus Mårtensson
Demystifying Open Distro for Elasticsearch
Suman Debnath
Future of Data
Shivam Ahuja
Tea Break
gRPC with C# and .Net Core
Mangesh Gaherwar
Panel 1
Essentials of Cloud security
Parveen Malik
Power platform and Dynamics 365
Deepesh Somani
Microservices - the gRPC Way
Viswanatha Swamy
Panel 2
Reserved
Reserved
Closing Note & Prize Distribution
Using NSubstitute For Flexible C# Test Doubles
Unit tests often become difficult to maintain when every dependency requires a long block of configuration. A test that should explain one business rule can instead be dominated by strict setups, argument matchers and verification syntax. NSubstitute offers a lighter style for creating test doubles, which can make C# tests easier to read while retaining control over important interactions.
This approach is particularly useful in .NET teams working with ASP.NET Core, Azure services, message queues and data access layers. For developers comparing mocking frameworks, the practical question is less about which library is universally best and more about how naturally each one expresses the behaviour a test needs.
| Area | NSubstitute | Moq |
|---|---|---|
| Substitute creation | Substitute.For<IEmailSender>() |
new Mock<IEmailSender>() |
| Return values | sender.SendAsync(...).Returns(true) |
mock.Setup(x => x.SendAsync(...)).ReturnsAsync(true) |
| Interaction checks | sender.Received().SendAsync(...) |
mock.Verify(x => x.SendAsync(...), Times.Once) |
| Default behaviour | Returns default or auto-values for many calls | Usually returns defaults unless configured |
| Readability | Focuses on calls made in the test | Focuses on explicit setup expressions |
| Main caution | Calls and argument matching need careful review | Verbose configuration can obscure intent |
Why Dynamic Mocking Matters In C# Tests
Dynamic mocking creates a substitute at runtime for an interface or virtual member. Instead of constructing a real database repository, payment gateway or notification client, a test supplies an object whose behaviour can be configured for the scenario. This keeps a unit test fast and prevents external systems from influencing its result.
NSubstitute is designed around this idea. Given an interface such as IInventoryService, a test can create a substitute without writing a hand-built fake:
var inventory = Substitute.For<IInventoryService>();
inventory.GetAvailableAsync("ABC-123")
.Returns(Task.FromResult(4));
The syntax describes the useful fact directly: when the system asks for stock for a particular product, return four units. There is no separate mock wrapper to unwrap, and the dependency can be passed into the class under test like any other implementation.
This style suits teams that value concise tests. In a Melbourne product squad or a Brisbane consultancy delivering several client systems, shorter test setup can reduce review time and make failures easier to diagnose. It also helps when a service has several dependencies but the test needs to configure only one of them.
NSubstitute And Moq Syntax Compared
Moq generally uses a Mock<T> object and an expression-based setup API. The equivalent example might look like this:
var inventory = new Mock<IInventoryService>();
inventory.Setup(x => x.GetAvailableAsync("ABC-123"))
.ReturnsAsync(4);
Both examples produce a useful substitute, yet they communicate intent differently. Moq makes the configuration operation explicit through Setup, while NSubstitute treats the call itself as the starting point for configuration. The NSubstitute version can feel closer to ordinary C# and usually requires less ceremony.
The contrast is clearer when checking interactions. With NSubstitute, a test can state:
await service.ReserveAsync("ABC-123", 2);
await inventory.Received(1)
.GetAvailableAsync("ABC-123");
Moq would typically use Verify with a lambda expression:
inventory.Verify(
x => x.GetAvailableAsync("ABC-123"),
Times.Once);
Neither approach is inherently incorrect. Moq can be a strong fit for teams that prefer every interaction to be declared through explicit setup and verification. NSubstitute tends to suit developers who want the test to read as a sequence of normal calls and assertions.
Creating Substitutes With Minimal Configuration
A useful feature of NSubstitute is its default behaviour. Unconfigured members generally return the default value for their type, while supported reference-type members can receive automatically generated substitutes. This lets a test configure only the branch that matters.
Consider a handler that depends on a repository, an audit logger and a notification service. A test for an invalid request may need no meaningful return value from any dependency:
var repository = Substitute.For<IOrderRepository>();
var audit = Substitute.For<IAuditLog>();
var notifications = Substitute.For<INotificationSender>();
var result = await handler.HandleAsync(request);
The test can then assert that validation failed and that no order was saved. There is no need to invent an irrelevant order object or configure every method called during object construction. This is dynamic test-double behaviour used carefully: the substitute supplies enough structure for the scenario without pretending to be a real data store.
Auto-values should still be treated with discipline. A default null, empty collection or nested substitute can hide an incomplete test if the assertion is too weak. For important domain outcomes, configure a meaningful response explicitly. The goal is reduced noise, not reduced precision.
This balance matters in Australian enterprise software, where applications often integrate with government records, banking platforms or large corporate workflows. A green test that passes because an unconfigured call quietly returned a default value can create false confidence during a release cycle.
Configuring Arguments And Async Members
NSubstitute supports exact arguments, argument matchers and return values for asynchronous methods. Exact matching is generally preferable when the input is part of the behaviour being tested:
pricing.GetPriceAsync("SKU-9", "AUD")
.Returns(Task.FromResult(19.95m));
When the exact value is not important, matchers such as Arg.Any<T>() or Arg.Is<T>() can keep the test focused:
pricing.GetPriceAsync(
Arg.Any<string>(),
"AUD")
.Returns(Task.FromResult(19.95m));
A predicate matcher is useful for business constraints:
pricing.GetPriceAsync(
Arg.Is<string>(sku => sku.StartsWith("SKU-")),
"AUD")
.Returns(Task.FromResult(19.95m));
For asynchronous APIs, modern NSubstitute versions generally allow a task-compatible value to be returned directly, though Task.FromResult remains clear and widely understood. Teams should align with the package version and project conventions rather than mixing styles without reason.
Argument matchers can become dangerous when applied too broadly. If every string is accepted, a test may pass even when the production code sends the wrong identifier. In an Australian ecommerce system handling AUD pricing, GST calculations and delivery zones from Perth to Cairns, the test should match the values that materially affect the outcome.
Verifying Calls Without Over-Specifying Behaviour
Interaction testing is valuable when a call is part of the contract. For example, a failed payment may need to publish an event exactly once, while a cached read may be expected to avoid calling the remote service. NSubstitute expresses these expectations with Received() and DidNotReceive():
await publisher.Received(1)
.PublishAsync(Arg.Any<OrderCancelled>());
await gateway.DidNotReceive()
.ChargeAsync(Arg.Any< decimal >());
The spacing in the generic matcher should follow the project formatter; the important point is that the test checks observable collaboration rather than private implementation details. You can also verify a call with a predicate:
await publisher.Received()
.PublishAsync(
Arg.Is<OrderCancelled>(
message => message.OrderId == order.Id));
A common mistake is verifying every call made by a class. That produces brittle tests: a harmless refactoring, such as combining two repository reads, can break a test even though the public result remains correct. Verify interactions when they protect a meaningful boundary, such as an email being sent, a transaction being committed or a message being published.
This distinction is useful for distributed .NET applications deployed across Australian regions. A service may use Azure queues, an API gateway and a regional database, so tests should protect important integration decisions without encoding every internal method call. The conference programme also reflects the broad ecosystem in which these patterns appear, from cloud computing to DevOps and web development.
Handling Pitfalls And Choosing A Team Standard
NSubstitute has a few rules that deserve attention. Argument matchers should be used only when configuring or checking a call, and they should not be passed casually into production methods. Calls made during substitute configuration can also be surprising when properties or nested members are involved. Clear, isolated configuration keeps the test intention visible.
Partial substitutes require particular care. They can be useful when a concrete class contains one virtual operation that should be replaced, but they may execute real code unexpectedly. Prefer substituting interfaces or small abstractions where possible. If a dependency is difficult to fake, that may indicate a design opportunity: separate external effects from domain logic and inject the boundary.
Moq remains a sensible choice for established codebases, especially where a team already has extensive helper methods, conventions and reviewer familiarity. Switching frameworks for fashion can create unnecessary migration work. NSubstitute is compelling when new tests are being written, when setup syntax is obscuring business intent, or when developers want a straightforward substitute-and-assert workflow.
For a new standard, assess more than line count. Check how well the framework handles async APIs, protected members, callbacks, argument matching, analyzers and the project’s target .NET version. Run a small pilot against real services in the codebase rather than relying on toy examples. A Sydney team working in a large Azure estate may value different features from a small Perth consultancy building a lightweight ASP.NET Core API.
Applying The Pattern In Real Australian Projects
A practical test suite usually combines NSubstitute with real domain objects, focused assertions and a small number of interaction checks. Use substitutes for unstable boundaries such as HTTP clients, repositories, clocks, queues and payment providers. Keep calculations, validation and mapping based on real implementations where they are fast and deterministic.
For example, a delivery-pricing service might receive an IShippingRatesClient, an IClock and a repository. The test can configure the client to return a rate for an Australian postcode, set the clock to a known date, and verify that the selected rate is persisted. It does not need to emulate the carrier’s entire API or reproduce every rule for remote and regional deliveries.
Local context can expose useful test cases. A system may need to distinguish Sydney metro delivery from a remote Northern Territory postcode, account for public holidays, or handle daylight-saving differences between New South Wales and Queensland. These details belong in explicit domain tests, while NSubstitute keeps network and persistence concerns isolated.
Teams also need to consider the market in which their software operates. Australian organisations commonly run mixed estates involving Microsoft 365, Azure, legacy .NET Framework services and newer containerised workloads. Contractors and permanent staff may rotate through projects, and a readable mocking convention reduces the time needed to understand unfamiliar tests. Whether developers call the afternoon an “arvo” or simply work through a release window, the useful standard is the same: configure the smallest meaningful behaviour, assert the business outcome, and verify only collaborations that matter.
1, CBD, Maharaj Surajmal Road, Near Yamuna Sports Complex, Delhi, 110032
GENERAL QUERIES
Manish Tewatia
manish@csharpcon.com
+91-9718-431-042
TICKET QUERIES
Atul Gupta
conference@csharpcon.com
+91-9910-125-804