Moq qui pratiquent les méthodes d'où l'Expression<Func<T, bool>> sont passés en paramètres
Je suis très nouveau pour les tests unitaires et les moqueries! Je suis en train d'écrire des tests unitaires qui couvre une partie du code qui interagit avec un magasin de données. L'accès aux données est encapsulé par IRepository:
interface IRepository<T> {
....
IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
....
}
Le code que je suis en train de tester, en utilisant un béton Cio avais mise en œuvre de IRepository ressemble à ceci:
public class SignupLogic {
private Repository<Company> repo = new Repository<Company>();
public void AddNewCompany(Company toAdd) {
Company existingCompany = this.repo.FindBy(c => c.Name == toAdd.Name).FirstOrDefault();
if(existingCompany != null) {
throw new ArgumentException("Company already exists");
}
repo.Add(Company);
repo.Save();
}
}
De sorte que je suis en essais la logique de SignupLogic.AddNewCompany() elle-même, plutôt que de la logique et le béton Référentiel, je suis moqueur jusqu'IRepository et le passage dans SignupLogic. La maquette Référentiel ressemble à ceci:
Mock<Repository> repoMock = new Mock<Repository>();
repoMock.Setup(moq => moq.FindBy(c => c.Name == "Company Inc")....
qui renvoie à une mémoire IEnumberable contenant une Entreprise de l'objet avec le nom de "Company Inc". L'unité de test qui appelle SignupLogic.AddNewCompany met en place une société avec des doublons de détails et essaie de se passer que dans, et j'affirme que ArgumentException est levée avec le message "la Société existe déjà". Ce test n'est pas en passant.
De débogage par le biais de l'unité de test et de AddNewCompany (), car il s'exécute, il semblerait que existingCompany est toujours null. En désespoir de cause, j'ai trouvé que si je mettre à jour SignupLogic.AddNewCompany() de sorte que l'appel à FindBy ressemble à ceci:
Company existingCompany = this.repo.FindBy(c => c.Name == "Company Inc").FirstOrDefault();
le test passe, ce qui me laisse croire que Moq est seulement en répondant à un code qui est exactement le même que j'ai configuré dans mon installation de test. Évidemment, ce n'est pas particulièrement utile dans les essais que le double de l'entreprise est rejeté par SignupLogic.AddNewCompany.
J'ai essayé la configuration de moq.FindBy(...) à l'utilisation.ItAny", mais qui ne causent pas de test à passer.
De tout ce que je suis en train de lire, il semblerait que les tests de dépistage des Expressions que j'essaie de n'est pas vraiment faisable avec Moq ici. Est-il possible? S'il vous plaît aider!
- Si votre objectif est de tester le retour, vous pouvez forcer votre Maquette cadre d'ignorer l'argument: se Moquer de.Organiser(() => repo.AllIncluding(x => x.Category == catégorie)) .IgnoreArguments() .Retourne (new List<Produit>{new Produit()}) .AsQueryable()); Dans l'exemple ci-dessus, je suis en utilisant une version gratuite de JustMock.
Vous devez vous connecter pour publier un commentaire.
Il est probablement exact que seul un
Expression
avec exactement la même structure (et des valeurs littérales) sera à la hauteur. Je vous suggère d'utiliser la surcharge deReturns()
qui vous permet d'utiliser les paramètres de la simulation est appelée avec:Dans
...
, vous pouvez utiliserpredicate
pour revenir à la concordance des entreprises (et peut-être même lancer une exception si l'appariement des entreprises n'est pas ce que vous attendiez). Pas très jolie, mais je pense que cela fonctionnera.companies
qui contient toutes les sociétés, puis.Returns((Expression<Func<Company, bool>> predicate) => companies.Where(predicate));
devrait fonctionner. Toutefois, si vous avez besoin de fonctionnalités plus avancées que cela, vous pourriez être mieux écrit une classe qui implémenteIRepository<Company>
plutôt que d'utiliser Moq, depuis la construction de complexes de comportement en se moque, c'est encombrant.Vous devriez être en mesure d'utiliser
It.IsAny<>()
pour accomplir ce que vous cherchez à faire. Avec l'utilisation deIt.IsAny<>()
vous pouvez régler simplement le type de retour de votre installation pour tester chaque branche de votre code.Premier Test, le retour d'une société, indépendamment de prédicat qui sera la cause de l'exception à jeter:
Deuxième épreuve, faire le type de retour d'une liste vide sorcière va provoquer ajouter d'être appelé.:
It.IsAny
en combinaison avec unReturn()
qui ne vérifie pas les paramètres, c'est que vous n'obtenez pas de vérifier que les paramètres sont ce qu'ils devraient être. Parfois, bien sûr, vous avez vraiment ne voulez accepter n'importe quel paramètre de la valeur, mais dans ce cas, vous voudrez probablement pour vérifier queSignupLogic
construit sa requête correctement (en utilisant le nom de la société, et non pas une autre propriété).m.FindBy(item=>item.CompanyID == 1)
. Une façon d'y parvenir est d'utiliser LambdaCompare: stackoverflow.com/questions/283537/.... Par l'utilisation de cette classe de comparaison, la nouvelle installation seraitExpression<Func<Company, bool>> testExpression = item => item.CompanyID == 1;repoMock.Setup(m => m.FindById(It.Is<Expression<Func<Company, bool>>>(criteria => LambdaCompare.Eq(criteria, testExpression)))).Returns(yourCompanyList)
Vous normalement seulement se moquer des types que vous possédez. Ceux que vous n'avez pas propre, ne devrait vraiment pas être moqué à cause de diverses difficultés. Si moqueur expressions - comme le nom de votre question implique, n'est pas la voie à suivre.
Dans Moq cadre. Il est important de mettre
.Returns()
pour les fonctions sinon c'est pas de correspondance. Donc, si vous ne l'avez pas fait, c'est votre problème.Repository
. LeExpression
n'est pas un simulacre; il est seulement utilisé pour mettre en correspondance les appels sur la maquette.Moq'ing Expression<Func<T, bool>> parameters